逻辑层
逻辑层负责反馈用户对界面操作的处理中心。
逻辑层是终端开发的“灵魂”。
而 VM 对象 是逻辑层规范的输入口
VM 对象
字段名 | 类型 | 说明 |
---|---|---|
props | Object | 声明当前组件可接收数据属性 props = { type, default } type为数据类型,default为数据默认值 |
data | Object | CML模板可直接使用的响应数据,是连接视图层的枢纽 |
methods | Object | 处理业务逻辑与交互逻辑的方法 |
watch | Object | 侦听属性,监听数据的变化,触发相应操作 |
computed | Object | CML模板可直接使用的计算属性数据,也是连接视图层的枢纽 |
beforeCreate | Function | 例初始化之后,数据和方法挂在到实例之前 一个页面只会返回一次 |
created | Function | 数据及方法挂载完成 |
beforeMount | Function | 开始挂载已经编译完成的cml到对应的节点时 |
mounted | Function | cml模板编译完成,且渲染到dom中完成 |
beforeDestroy | Function | 实例销毁之前 |
destroyed | Function | 实例销毁后 |
响应式数据绑定系统
响应式数据绑定意味着开发者只需关心逻辑处理,通过数据绑定的形式,当数据变化时视图自动更新。
通过这个简单的例子来看:
<template>
<view>
<text>Hello {{ name }}!</text>
<button c-bind:onclick="changeName">Click me!</button>
</view>
</template>
<script>
class Index {
data = {
name: 'Chameleon',
};
methods = {
changeName: function(e) {
// sent data change to view
this.name = 'CML';
},
};
}
export default new Index();
</script>
框架首先将逻辑层数据中的 name 与视图层的 name 进行了绑定,所以打开页面的时候会显示 HelloCML; 当点击按钮的时候,视图层会发送 changeName 的事件给逻辑层,逻辑层找到并执行对应的事件处理函数; 回调函数触发后,逻辑层执行数据赋值的操作,将 data 中的 name 从 CML 变为 CML,因为该数据和视图层已经绑定了,从而视图层会自动改变为 Hello CML!。
生命周期
每个 CML 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 节点 并在数据变化时更新 节点 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给开发者在不同阶段添加自己的代码的机会。
chameleon 为组件和 页面 提供了一系列生命周期事件,保障应用有序执行。 如果你想使用某个端特定的生命周期,请从业务出发使用多态接口接收特定的生命周期事件回调。
钩子 | 执行时机 | 详细 |
---|---|---|
beforeCreate | 实例初始化之后,数据和方法挂在到实例之前 | 页面会在该生命周期中返回传入当前页面的参数对象 |
created | 数据及方法挂载完成 | 页面会在该生命周期中返回传入当前页面的参数对象 |
beforeMount | 开始挂载已经编译完成的cml到对应的节点时 | 在页面会在该生命周期中返回传入当前页面的参数对象 |
mounted | cml模板编译完成,且渲染到dom中完成 | |
beforeDestroy | 实例销毁之前 | |
destroyed | 实例销毁后 |
页面 Page 独有生命周期
onShow()
chameleon-runtime@0.2.0 开始支持
页面显示/切入前台时触发
onHide()
chameleon-runtime@0.2.0 开始支持
页面隐藏/切入后台时触发
** 注意:页面不会在 onShow、onHide 回调函数中返回页面参数 **
生命周期回调函数
beforeCreate(Object res)
参数说明
名称 | 类型 | 说明 |
---|---|---|
res | Object | 仅有页面在该生命周期回调函数中会 返回对象res: res = { query } query 是打开当前页面路径中的参数 |
created(Object res)
参数说明
名称 | 类型 | 说明 |
---|---|---|
res | Object | 仅有页面在该生命周期回调函数中会 返回对象res: res = { query } query 是打开当前页面路径中的参数 |
beforeMount(Object res)
参数说明
名称 | 类型 | 说明 |
---|---|---|
res | Object | 仅有页面在该生命周期回调函数中会 返回对象res: res = { query } query 是打开当前页面路径中的参数 |
钩子示例
<template>
<view> </view>
</template>
<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>
生命周期多态
CML 在 *.[web|weex|wx].cml 文件中支持生命周期的多态,可以针对不同的平台添加专属钩子函数。
假设有一个页面home.cml,需要使用小程序页面分享生命周期微信端 onShareAppMessage,可以如下实现:
- 项目根目录执行 cml init component,选择 multimode-interface 多态接口,输入 interface name: lifecycleInterface,自动生成src/components/lifecycleInterface
- 在src/components/lifecycleInterface/lifecycleInterface.cml多态接口中,添加如下代码:
<script cml-type="interface">
interface LifecycleInterfaceInterface {
onShareAppMessage(): void;
}
</script>
<script cml-type="web">
class Method implements LifecycleInterfaceInterface {
onShareAppMessage() {
console.log('web share');
}
}
export default new Method();
</script>
<script cml-type="weex">
class Method implements LifecycleInterfaceInterface {
onShareAppMessage() {
console.log('weex share');
}
}
export default new Method();
</script>
<script cml-type="wx">
class Method implements LifecycleInterfaceInterface {
onShareAppMessage() {
console.log('wx share');
}
}
export default new Method();
</script>
<script cml-type="alipay">
class Method implements LifecycleInterfaceInterface {
onShareAppMessage() {
console.log('alipay share');
}
}
export default new Method();
</script>
<script cml-type="baidu">
class Method implements LifecycleInterfaceInterface {
onShareAppMessage() {
console.log('baidu share');
}
}
export default new Method();
</script>
- 在 home.cml 文件,使methods合并lifecycleInterface多态方法
<template>
<view>
<text>home页面</text>
<view>
</template>
<script>
import lifecycleInterface from '../../components/lifecycleInterface/lifecycleInterface'
class Home {
data = {}
computed = {}
watch = {}
methods = {
...lifecycleInterface
}
beforeCreate(res) {}
created() {}
}
export default new Home()
</script>
计算属性 computed
对于模板内任何复杂逻辑,你都应当使用计算属性
示例
<template>
<view>
<text>Original message: "{{ message }}"</text>
<text>Computed reversed message: "{{ reversedMessage }}"</text>
</view>
</template>
<script>
class Index {
data = {
message: 'Hello',
};
computed = {
// 计算属性的 getter
reversedMessage: function() {
return this.message
.split('')
.reverse()
.join('');
},
};
}
export default new Index();
</script>
结果:
Original message: "Hello"
Computed reversed message: "olleH"
这里我们声明了一个计算属性 reversedMessage。 我们提供的函数将用作属性 reversedMessage 的 getter 函数,当 message 发生改变时,reversedMessage 也会更新
侦听属性 watch
提供了一种更通用的方式来观察和响应实例上的数据变动
示例
<template>
<view>
<text>fullName is : "{{ fullName }}"</text>
</view>
</template>
<script>
class Index {
data = {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar',
};
watch = {
firstName: function(newV, oldV) {
this.fullName = newV + ' ' + this.lastName;
},
lastName: function(newV, oldV) {
this.fullName = this.firstName + ' ' + newV;
},
};
}
export default new Index();
</script>
除了 watch 选项之外,你还可以使用命令式的 this.$watch API。
但是,上面代码是命令式且重复的。将它与计算属性的版本进行比较:
<script>
class Index {
data = {
firstName: 'Foo',
lastName: 'Bar',
};
computed = {
fullName: function() {
return this.firstName + ' ' + this.lastName;
},
};
}
</script>
所以,不要滥用 watch ~
API
CML 框架提供了丰富的多态接口,可以调起各端提供的原生能力,如系统信息、元素节点信息、动画效果、本地存储、网络请求、地理位置等。请参考API 文档。
代码示例
import cml from 'chameleon-api';
cml.showToast({
message: 'Hello world!',
duration: 1000,
});
通常,在 CML API 有以下几种类型:
通用 API
大多数 API 都是异步 API,如 cml.get 等。这类 API 接口通常都接受一个 Object 类型的参数,返回 Promise ,对应请求成功和失败回调,支持 then 链式调用。
代码示例
cml
.get({
url: 'https://cml.com/api/user/1',
})
.then(
(res) => {
cml.showToast({
message: JSON.stringify(res),
duration: 2000,
});
},
(err) => {
cml.showToast({
message: JSON.stringify(err),
duration: 2000,
});
},
);
运行时相关 API
代码示例
import a from 'a.js';
export { a };
数据管理 Store API
代码示例
// store.js
import createStore from 'chameleon-store';
const store = createStore({ state, mutations, actions, getters, modules });
export default store;
更多建议: