资讯专栏INFORMATION COLUMN

cml迁移指南(CML Migrate Guide)

FreeZinG / 1960人阅读

摘要:今天,为了让大家的项目优雅升级,快速接入,给你带来一份丰盛的迁移指南目录结构和微信小程序一样,包含一个描述整体程序的和多个描述各自页面的。

cml 作为真正让一套代码运行多端的框架,提供标准的MVVM模式,统一开发各类终端。

同时,拥有各端独立的 运行时框架(runtime)数据管理(store)组件库(ui)接口(api)

此外,cml在跨端能力加强能力统一表现一致等方面做了许多工作。

今天,为了让大家的项目优雅升级,快速接入,给你带来一份丰盛的cml迁移指南~

目录结构

和微信小程序一样,cml 包含一个描述整体程序的 app 和多个描述各自页面的 page

小程序目录结构
.
├── components // 包含各个组件
├── pages // 包含各个页面
├── app.js // 包含各个组件
├── app.js  // 应用启动入口
├── app.json // 全局配置
├── app.wxss // 全局样式
└── project.config.json // 项目配置文件
cml目录结构
.
├── dist // 各个端构建结果
│   ├── alipay 
│   ├── baidu 
│   ├── wx 
│   ├── web  
│   ├── weex 
│   └── config.json // 跨端配置map映射表
├── node_modules // 第三方库
├── mock // 模拟 接口数据 和 模板数据
├── src  // 源代码开发目录
│   ├── app // 应用启动入口
│   ├── assets // 静态资源
│   ├── components // 包含组件
│   ├── pages  // 包含页面
│   ├── store //数据管理
│   └── router.config.json // 路由配置文件
├── chameleon.config.js // 项目配置文件
└── package.json // npm包配置文件
如何修改配置

在小程序项目里面,分为:

小程序 —— 项目配置

可以在项目根目录使用 project.config.json 文件对项目进行配置。

配置示例:

{
  "miniprogramRoot": "./src",
  "debugOptions": {}
}
小程序 —— 全局配置

小程序根目录下的 app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等

配置示例:

{
  "pages": ["pages/index/index", "pages/logs/index"],
  "window": {
    "navigationBarTitleText": "Demo"
  },
  "networkTimeout": {
    "request": 10000,
    "downloadFile": 10000
  }
}
小程序 —— 页面配置

每一个小程序页面也可以使用 .json 文件来对本页面的窗口表现进行配置。

页面的配置只能设置 app.json 中部分 window 配置项的内容,页面中配置项会覆盖 app.jsonwindow 中相同的配置项。

配置示例:

{
  "navigationBarBackgroundColor": "#ffffff",
  "navigationBarTextStyle": "black",
  "navigationBarTitleText": "微信接口功能演示",
  "backgroundColor": "#eeeeee",
  "backgroundTextStyle": "light"
}

同样,在 cml项目里面,分为:

cml —— 项目配置

chameleon.config.js 为项目的配置文件,你可以定制化构建,比如是否带hash,是否压缩等等。

配置示例:

// 设置静态资源的线上路径
const publicPath = "//www.static.chameleon.com/static";
// 设置api请求前缀
const apiPrefix = "https://api.chameleon.com";
// 合并配置
cml.config.merge({
  wx: {
    build: {apiPrefix}
  },
  alipay: {
    build: {apiPrefix}
  },
  baidu: {
    build: {apiPrefix}
  },
  web: {
    dev: {
      hot: true,
      console: true
    },
    build: {
      publicPath: `${publicPath}/web`,
      apiPrefix
    }
  },
  weex: {
    build: {
      publicPath: `${publicPath}/weex`,
      apiPrefix
    }
  }
})
cml —— 全局配置

cml 项目 app 目录下的 app.cml 文件的 cml —— 页面/组件配置

通过 usingComponents 配置 组件路径 注册引用的组件。

配置示例:

如何使用路由能力 小程序配置路由

app.json 配置项列表的 pages 字段用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径+文件名 信息。

数组的第一项代表小程序的初始页面(首页)。新增/减少页面,需要对 pages 数组进行修改。

如果项目有 pages/index/index.wxmlpages/logs/logs.wxml 两个页面,则需要在 app.json 中写

{
  "pages": ["pages/index/index", "pages/logs/logs"]
}
cml配置路由

src/router.config.json 是路由的配置文件,cml 内置了一套各端统一的路由管理方式。相应有 cml 路由配置映射如下:

{
  "mode": "history",
  "domain": "https://www.chameleon.com",
  "routes":[
    {
      "url": "/cml/h5/index",
      "path": "/pages/index/index",
      "mock": "index.php"
    },
    {
      "url": "/cml/h5/logs",
      "path": "pages/logs/logs",
      "mock": "logs.php"
    }
  ]
}

文件名不需要写文件后缀,cml框架会自动去寻找对于位置的 .cml 文件进行处理。

小程序使用路由

打开新页面:调用 API wx.navigateTo

页面重定向:调用 API wx.redirectTo

页面返回:调用 API wx.navigateBack

打开另一个小程序:调用 API wx.navigateToMiniProgram

返回到上一个小程序:调用 API wx.navigateBackMiniProgram

cml使用路由

依据统一资源索引URI,自适应打开不同环境同一路由PATH:

打开新页面:调用 chameleon-api cml.navigateTo

页面重定向:调用 chameleon-api cml.redirectTo

页面返回:调用 chameleon-api cml.navigateBack

打开另一个跨端应用:调用 chameleon-api cml.open

返回到上一个跨端应用:调用 chameleon-api cml.close

如何注册 如何注册程序 小程序注册程序

在小程序项目里面,App() 函数用来注册一个小程序。接受一个 Object 参数,其指定小程序的生命周期回调等。

示例代码

App({
  onLaunch(options) {
    // Do something initial when launch.
  },
  globalData: "I am global data"
})
cml注册程序

示例代码

细心的你会发现,

小程序中app.json app.js app.wxsssrc/app/app.cml的对应关系如下

小程序 app.js cml项目 src/app/app.cml
app.js
app.wxss
app.json
如何注册页面 小程序注册页面

在小程序项目里面,Page(Object) 函数用来注册一个页面。接受一个 Object 类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。

示例代码:

// index.js
Page({
  data: {
    text: "This is page data."
  },
  changeText: function(e) {
    // sent data change to view
    this.setData({
      text: "CML"
    })
  }
})
cml注册页面

示例代码

如何注册组件 小程序注册组件

在小程序项目里面,
Component(Object) 构造器可用于定义组件,调用 Component 构造器时可以指定组件的属性、数据、方法等。

示例代码

Component({
  properties: {
    myProperty: { // 属性名
      type: String, // 类型(必填)
      value: "" // 属性初始值(可选)
    },
    myProperty2: String // 简化的定义方式
  },
  data: {
    text: ""
  }, // 私有数据,可用于模板渲染

  // 生命周期函数,可以为函数,或一个在methods段中定义的方法名
  attached() { }, 
  ready() { },
  methods: {
    onMyButtonTap() {
      this.setData({
        // 更新属性和数据的方法与更新页面数据的方法类似
        text: "wx"
      })
    }
  }
})
cml注册组件

示例代码

如何声明生命周期

统一各端应用生命周期的定义,是跨端框架的重要组成,也是迁移的必经之路。

小程序声明生命周期

可以在 App(Object)Page(Object)Component(Object) 传入Object参数,其指定小程序的生命周期回调等

代码示例

// index.js
Page({
  onLoad(options) {
    // Do some initialize when page load.
  },
  onReady() {
    // Do something when page ready.
  },
  onShow() {
    // Do something when page show.
  },
  onHide() {
    // Do something when page hide.
  },
  onUnload() {
    // Do something when page close.
  },
  onShareAppMessage() {
    // return custom share data when user share.
  }
})
cml声明生命周期

.cml 文件 App 生命周期 映射

小程序 app.js中的生命周期 -> cml src/app/app.cml

小程序 chameleon
onLaunch beforeCreate
onShow mounted
onHide destroyed
Page 生命周期 映射

小程序 Page()中的生命周期 -> cml src/pages/mypage/mypage.cml

小程序 chameleon
onLoad beforeCreate
onShow mounted
onUnload destroyed
onReady 生命周期多态
onHide 生命周期多态
onShareAppMessage 生命周期多态
Component 生命周期 映射

小程序 Component()中的生命周期 -> cml src/components/mycomponent/mycomponent.cml

小程序 chameleon
created created
attached beforeMount
ready mounted
detached destroyed
生命周期总结

每个 cml 实例(AppPageComponent)在被创建时都要经过一系列的初始化过程 ————

例如,需要设置数据监听、编译模板、将实例挂载到 CML节点 并在数据变化时更新 CML节点 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给开发者在不同阶段添加自己的代码的机会。

cmlApp页面Page组件Component 提供了一系列生命周期事件,保障应用有序执行。

另外,如果你想使用某个端特定的生命周期,你可以从业务出发使用 生命周期多态。

数据如何响应到视图

如今,双向数据绑定&单向数据流 已深入开发者日常,MVMM开发模式算是框架标配。

数据绑定、条件渲染、列表渲染 是如何书写的呢?

示例代码

小程序使用数据响应


    
  {{message}}
  
  WEBVIEW
  APP
  MINA
    
  {{item}}
// page.js
Page({
  data: {
    message: "Hello MINA!",
    view: "MINA",
    array: [1, 2, 3, 4, 5]
  },
  onLoad() {
    this.setData({
      message: "wx"
    })
  }
})
cml使用数据响应

数据响应总结

cml运行时框架 提供了跨端响应式数据绑定系统(Data binding),当做数据修改的时候,只需要在逻辑层修改数据,视图层就会做相应的更新。

只需要将 view<-->model 交互部分逻辑,作简单迁移,便可使它成为跨多端的数据响应系统。

事件交互

cml 支持一些基础的事件,保障各端效果(类型绑定事件对象)一致运行。

示例代码

小程序使用事件

Click me!
// page.js
Page({
  tapName(event) {
    console.log(event)
  }
})
cml使用事件

事件使用总结

同时,还支持自定义事件,用于父子组件之间的通信。

另外,如果你想要使用某个端特定的事件,cml 并不会限制你的自由发挥,你可以从业务出发使用 组件多态 或者 接口多态 差异化实现功能。

布局和外观

各端描述 布局和外观 的层叠样式表(CSS)实现存在差异,包括不限于 布局盒模型定位文本

所以, cml 框架内置跨端一致性基础样式能力。

并且,定义了用于描述页面的样式规范CMSS(Chameleon Style Sheet)。

如何导入外部样式

使用 @import 语句可以导入外联样式表,@import 后跟需要导入的外联样式表的相对路径,用 ; 表示语句结束。

小程序导入外部样式

示例代码:

/** common.wxss **/
.small-p {
  padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
  padding:15px;
}
cml导入外部样式

详细文档

示例代码:

/** common.css **/
.small-p {
  padding: 5px;
}

样式使用总结

同时,为了统一多端尺寸单位,呈现效果一致,同时页面响应式布局,cml 项目统一采用 cpx 作为尺寸单位,规定以屏幕750px(占满屏幕)视觉稿作为标准。

而且,各端样式表拥有的能力 不尽相同,是项目迁移的主要阵地之一。

另外,如果你想要使用某个端特定的样式能力,cml 并不会限制你的自由发挥,你可以从业务出发使用 样式多态

注意:由于chameleon应用是 跨多端web native 小程序框架,如果需要跨native,必须使用 flexbox 进行样式布局!!!

组件

cml 项目一切皆组件。组件(Component)是视图的基本组成单元。

框架为开发者提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。

如:

同时,cml 支持简洁的组件化编程。

自定义组件

开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用。自定义组件在使用时与基础组件非常相似。

如何创建自定义组件
小程序创建自定义组件

代码示例:

Component({
  properties: {
    // 这里定义了innerText属性,属性值可以在组件使用时指定
    innerText: {
      type: String,
      value: "default value",
    }
  },
  data: {
    // 这里是一些组件内部数据
    someData: {}
  },
  methods: {
    // 这里是一个自定义方法
    customMethod() {}
  }
})
cml创建自定义组件

示例代码

如何使用自定义组件

使用已注册的自定义组件前,首先要进行引用声明。此时需要提供每个自定义组件的标签名和对应的自定义组件文件路径。

小程序使用自定义组件

代码示例:

page.json 中进行引用声明

{
  "usingComponents": {
    "component-tag-name": "path/to/the/custom/component"
  }
}

page.wxml 中使用


  
  
cml使用自定义组件

代码示例:

page.cml

page.cml