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.json
的 window
中雷同的设置项。
设置示例:
{
"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
文件的 <script cml-type="json" />
用来对 cml
运用 举行全局设置,具有 跨端设置 和 差别化 的才能
设置示例:
<script cml-type="json">
{
"base": {
"window": {
"navigationBarTitleText": "各个端配合title",
},
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于小顺序位置接口的结果展现"
}
}
},
"wx": {
"window": {
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "差别化 title",
"navigationBarTextStyle":"black"
}
},
"baidu": {
"window": {
"backgroundTextStyle": "light"
}
},
"alipay": {
"window": {
"defaultTitle": "Chameleon"
}
}
}
</script>
cml —— 页面/组件设置
经由历程 usingComponents
设置 组件途径
注册援用的组件。
设置示例:
<script cml-type="json">
{
"base": {
"usingComponents": {
"navi": "/components/navi/navi",
"navi-npm": "cml-test-ui/navi/navi"
}
},
"wx": {
},
"alipay": {
},
"baidu": {
},
"web": {
},
"weex": {
}
}
</script>
怎样运用路由才能
小顺序设置路由
app.json 设置项列表的 pages
字段用于指定小顺序由哪些页面构成,每一项都对应一个页面的 途径+文件名
信息。
数组的第一项代表小顺序的初始页面(首页)。新增/削减页面,须要对 pages
数组举行修正。
假如项目有 pages/index/index.wxml
、pages/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注册顺序
示例代码
<script>
import store from '../store/index.js'
import routerConfig from '../router.config.json';
class App {
data = {
store,
routerConfig
}
created(res) {
}
}
export default new App();
</script>
仔细的你会发明,
小顺序中app.json app.js app.wxss
和 src/app/app.cml
的对应关联以下
小顺序 app.js | cml项目 src/app/app.cml |
---|---|
app.js | <script></script> |
app.wxss | <style></style> |
app.json | <script cml-type="json"></script> |
怎样注册页面
小顺序注册页面
在小顺序项目内里,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注册页面
示例代码
<script>
class Index {
data = {
text: 'Chameleon'
}
methods = {
changeText: function(e) {
// sent data change to view
this.text = 'CML';
}
}
computed = {}
watch = {}
};
export default new Index();
</script>
怎样注册组件
小顺序注册组件
在小顺序项目内里,Component(Object)
组织器可用于定义组件,挪用 Component
组织器时能够指定组件的属性、数据、要领等。
示例代码
Component({
properties: {
myProperty: { // 属性名
type: String, // 范例(必填)
value: '' // 属性初始值(可选)
},
myProperty2: String // 简化的定义体式格局
},
data: {
text: ''
}, // 私有数据,可用于模板衬着
// 性命周期函数,能够为函数,或一个在methods段中定义的要领名
attached() { },
ready() { },
methods: {
onMyButtonTap() {
this.setData({
// 更新属性和数据的要领与更新页面数据的要领类似
text: 'wx'
})
}
}
})
cml注册组件
示例代码
<script>
class MyComponent {
props = {
myProperty: { // 属性名
type: String, // 范例(必填)
default: '' // 属性初始值(可选)
},
myProperty2: String // 简化的定义体式格局
}
data = {
text: ''
} // 私有数据,可用于模板衬着
beforeMount() {}
mounted() {}
methods = {
onMyButtonTap() {
this.text = 'cml'
}
}
computed = {}
watch = {}
};
export default new MyComponent();
</script>
怎样声明性命周期
一致各端运用性命周期的定义,是跨端框架的重要构成,也是迁徙的必经之路。
小顺序声明性命周期
能够在 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
文件 <script />
代码块返回的对象实例,其指定性命周期回调
示例代码
<script>
class Index {
beforeCreate(query) {
// data数据挂载到this根节点上之前,以及methods统统要领挂载到实例根节点之前
// 注重:只用页面的 beforeCreate钩子 会返回页面query
console.log('App beforeCreate: 翻开当前页面途径中的参数是 ', query)
}
created() {
// data,methods内里的这些events挂载完成
console.log('App created')
}
beforeMount() {
// 最先挂载已编译完成的cml到对应的节点时
console.log('App beforeMount')
}
mounted() {
// cml模板编译完成,且衬着到dom中完成,在全部性命周期中只实行一次
console.log('App mounted')
}
beforeDestroy() {
// 实例烧毁前
console.log('App beforeDestroy')
}
destroyed() {
// 实例烧毁后
console.log('App destroyed')
}
};
export default new Index();
</script>
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
实例(App
、Page
、Component
)在被建立时都要经由一系列的初始化历程 ————
比方,须要设置数据监听、编译模板、将实例挂载到 CML节点
并在数据变化时更新 CML节点
等。同时在这个历程当中也会运转一些叫做性命周期钩子的函数,这给开辟者在差别阶段增加本身的代码的时机。
cml
为App
、页面Page
、组件Component
供应了一系列性命周期事宜,保证运用有序实行。
别的,假如你想运用某个端特定的性命周期,你能够从营业动身运用 性命周期多态。
数据怎样相应到视图
现在,双向数据绑定&单向数据流 已深切开辟者一样平常,MVMM开辟形式算是框架标配。
示例代码
小顺序运用数据相应
<!--wxml-->
<view class="scroller-wrap">
<!--数据绑定-->
<view>{{message}}</view>
<!--前提衬着-->
<view wx:if="{{view == 'WEBVIEW'}}">WEBVIEW</view>
<view wx:elif="{{view == 'APP'}}">APP</view>
<view wx:else="{{view == 'MINA'}}">MINA</view>
<!--列表衬着-->
<view wx:for="{{array}}" wx:for-index="index" wx:for-item="item">{{item}}</view>
</view>
// page.js
Page({
data: {
message: 'Hello MINA!',
view: 'MINA',
array: [1, 2, 3, 4, 5]
},
onLoad() {
this.setData({
message: 'wx'
})
}
})
cml运用数据相应
<template>
<!--index.cml-->
<view class="scroller-wrap">
<!--数据绑定-->
<view>{{message}}</view>
<!--前提衬着-->
<view c-if="{{view == 'WEBVIEW'}}">WEBVIEW</view>
<view c-else-if="{{view == 'APP'}}">APP</view>
<view c-else="{{view == 'MINA'}}">MINA</view>
<!--列表衬着-->
<view c-for="{{array}}" c-for-index="index" c-for-item="item">{{item}}</view>
</view>
</template>
<script>
class Index {
data = {
message: 'Hello MINA!',
view: 'MINA',
array: [1, 2, 3, 4, 5]
}
beforeCreate () {
this.message = 'cml'
}
};
export default new Index();
</script>
数据相应总结
cml
运转时框架 供应了跨端相应式数据绑定体系(Data binding),当作数据修正的时刻,只须要在逻辑层修正数据,视图层就会做相应的更新。
只须要将 view<-->model
交互部份逻辑,作简朴迁徙,便可以使它成为跨多端的数据相应体系。
事宜交互
cml
支撑一些基础的事宜,保证各端结果(范例
、绑定
、事宜对象
)一致运转。
示例代码
小顺序运用事宜
<!--wxml-->
<view id="tapTest" data-hi="WeChat" bindtap="tapName">Click me!</view>
// page.js
Page({
tapName(event) {
console.log(event)
}
})
cml运用事宜
<template>
<view id="tapTest" data-hi="WeChat" c-bind:tap="tapName">
<text>Click me!</text>
</view>
</template>
<script>
class Index {
methods = {
tapName(e) {
// 打印事宜对象
console.log('事宜对象:', e);
}
}
}
export default new Index();
</script>
事宜运用总结
同时,还支撑自定义事宜,用于父子组件之间的通讯。
别的,假如你想要运用某个端特定的事宜,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;
}
<!-- app.cml -->
<style>
@import './common.css';
.middle-p {
padding:15 cpx;
}
</style>
款式运用总结
同时,为了一致多端尺寸单位,显现结果一致,同时页面相应式规划,cml
项目一致采纳 cpx 作为尺寸单位,划定以屏幕750px(占满屏幕)视觉稿作为范例。
而且,各端款式表具有的才能 不尽雷同,是项目迁徙的重要阵地之一。
别的,假如你想要运用某个端特定的款式才能,cml
并不会限定你的自由发挥,你能够从营业动身运用 款式多态
注重:因为chameleon运用是 跨多端web native 小顺序
框架,假如须要跨native
,必需运用 flexbox 举行款式规划!!!
组件
cml
项目统统皆组件。组件(Component)是视图的基础构成单位。
框架为开辟者供应了一系列基础组件,开辟者能够经由历程组合这些基础组件举行疾速开辟。
如:
<template>
<view>
<view>view 基础组件</view>
<text>text 基础组件</text>
</view>
</template>
同时,cml
支撑简约的组件化编程。
自定义组件
开辟者能够将页面内的功用模块笼统成自定义组件,以便在差别的页面中重复运用。自定义组件在运用时与基础组件异常类似。
怎样建立自定义组件
小顺序建立自定义组件
代码示例:
Component({
properties: {
// 这里定义了innerText属性,属性值能够在组件运用时指定
innerText: {
type: String,
value: 'default value',
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义要领
customMethod() {}
}
})
cml建立自定义组件
示例代码
<script>
class MyComponent {
props = {
// 这里定义了innerText属性,属性值能够在组件运用时指定
innerText: {
type: String,
value: 'default value',
}
}
data = {
// 这里是一些组件内部数据
someData: {}
}
methods = {
// 这里是一个自定义要领
customMethod() {}
}
computed = {}
watch = {}
};
export default new MyComponent();
</script>
怎样运用自定义组件
运用已注册的自定义组件前,首先要举行援用声明。此时须要供应每一个自定义组件的标署名和对应的自定义组件文件途径。
小顺序运用自定义组件
代码示例:
在 page.json
中举行援用声明
{
"usingComponents": {
"component-tag-name": "path/to/the/custom/component"
}
}
在 page.wxml
中运用
<view>
<!-- 以下是对一个自定义组件的援用 -->
<component-tag-name inner-text="Some text"></component-tag-name>
</view>
cml运用自定义组件
代码示例:
在 page.cml
中<script cml-type='json' />
举行援用声明
<script cml-type="json">
{
"base": {
"usingComponents": {
"component-tag-name": "path/to/the/custom/component"
}
}
}
</script>
在 page.cml
中<template />
运用
<template>
<view>
<!-- 以下是对一个自定义组件的援用 -->
<component-tag-name inner-text="Some text"></component-tag-name>
</view>
</template>
怎样完成父子组件事宜通讯
事宜体系是组件间通讯的重要体式格局之一。自定义组件能够触发恣意的事宜,援用组件的页面能够监听这些事宜。
小顺序组件通讯
代码示例:
<!-- 页面 page.wxml -->
<view>
<my-component bindcustomevent="onMyEvent"></my-component>
</view>
// 页面 page.js
Page({
methods: {
onMyEvent(e) {
console.log(e.detail) // 自定义组件触发事宜时供应的detail对象
}
}
})
<!-- 组件 my-component.wxml -->
<view>
<button bindtap="onTap">点击这个按钮将触发“myevent”事宜</button>
</view>
// 组件 my-component.js
Component({
methods: {
onTap() {
this.triggerEvent('customevent', {}) // 触发 自定义组件事宜
}
}
})
cml组件通讯
代码示例:
<!-- 页面 page.cml -->
<template>
<view>
<my-component c-bind:customevent="onMyEvent"></my-component>
</view>
</template>
<script>
class Index {
methods = {
// 这里是一个自定义要领
onMyEvent(e) {
console.log(e.detail) // 自定义组件触发事宜时供应的detail对象
}
}
};
export default new Index();
</script>
<script cml-type="json">
{
"base": {
"usingComponents": {
"my-component": "path/to/the/custom/component"
}
}
}
</script>
<!-- 页面 path/to/the/custom/component.cml -->
<template>
<view>
<button c-bind:tap="onTap">点击这个按钮将触发“myevent”事宜</button>
</view>
</template>
<script>
class MyComponent {
methods = {
// 这里是一个自定义要领
onTap() {
this.$cmlEmit('customevent', {}) // 触发 自定义组件事宜
}
}
};
export default new MyComponent();
</script>
<script cml-type="json">
{}
</script>
组件运用总结
和小顺序一样,cml框架
供应了大批内置组件和扩大组件,抹平多端差别,便于开辟者经由历程组合这些组件,建立出壮大的运用顺序。
扩大组件须要分外引入。如:
<script cml-type="json">
{
"base": {
"usingComponents": {
"c-dialog": "cml-ui/components/c-dialog/c-dialog"
}
}
}
</script>
在实行 cml build
构建打包时,cml 框架
会按需打包援用的内置组件和扩大组件,为代码瘦身。
内置组件和扩大组件 都是支撑跨多端的,关于一些没有供应的某个端的组件,能够经由历程组件多态来完成。
假如愿望运用小顺序端的原生组件,那末能够在原生标签前加上 origin-*
,cml
框架会衬着原生组件参考
注重:origin-*
只能在灰度区文件中运用!!
如在 map.wx.cml
文件中运用原生舆图组件 <map/>
:
<!-- map.wx.cml -->
<template>
<origin-map
id="map"
longitude="113.324520"
latitude="23.099994"
controls="{{controls}}"
bindcontroltap="controltap"
style="width: 100%; height: 300px;"
></origin-map>
</template>
怎样挪用平台接口才能
在小顺序内里,能够经由历程微信原生 API
,调起如猎取用户信息,当地存储,付出功用等。
示例代码
try {
wx.setStorageSync('name', 'Hanks')
} catch (e) {
console.error(e)
}
一样,在 cml 项目内里能够如许挪用:
示例代码
import cml from 'chameleon-api'
cml.setStorage('name', 'Hanks').then((res)=>{
console.log(res)
},function(e){
console.error(e)
})
接口运用总结
cml
框架供应了雄厚的多态接口,能够调起各端供应的原生才能,如体系信息、元素节点信息、动画结果、当地存储、收集要求、地理位置等。请参考 API 文档。
chameleon-api
供应的接口都是支撑跨多端的,关于一些没有供应的某个端的原生接口,能够经由历程接口多态来挪用。
迁徙实例
下面给出各端(vue、weex、小顺序)迁徙cml指南
以及 cml 导出组件到各端指南
的详细迁徙文档: