邏輯層負(fù)責(zé)反饋用戶對(duì)界面操作的處理中心。
邏輯層是終端開發(fā)的“靈魂”。
而 VM 對(duì)象 是邏輯層規(guī)范的輸入口
字段名 | 類型 | 說明 |
---|---|---|
props | Object | 聲明當(dāng)前組件可接收數(shù)據(jù)屬性 props = { type, default } type為數(shù)據(jù)類型,default為數(shù)據(jù)默認(rèn)值 |
data | Object | CML模板可直接使用的響應(yīng)數(shù)據(jù),是連接視圖層的樞紐 |
methods | Object | 處理業(yè)務(wù)邏輯與交互邏輯的方法 |
watch | Object | 偵聽屬性,監(jiān)聽數(shù)據(jù)的變化,觸發(fā)相應(yīng)操作 |
computed | Object | CML模板可直接使用的計(jì)算屬性數(shù)據(jù),也是連接視圖層的樞紐 |
beforeCreate | Function | 例初始化之后,數(shù)據(jù)和方法掛在到實(shí)例之前 一個(gè)頁面只會(huì)返回一次 |
created | Function | 數(shù)據(jù)及方法掛載完成 |
beforeMount | Function | 開始掛載已經(jīng)編譯完成的cml到對(duì)應(yīng)的節(jié)點(diǎn)時(shí) |
mounted | Function | cml模板編譯完成,且渲染到dom中完成 |
beforeDestroy | Function | 實(shí)例銷毀之前 |
destroyed | Function | 實(shí)例銷毀后 |
響應(yīng)式數(shù)據(jù)綁定意味著開發(fā)者只需關(guān)心邏輯處理,通過數(shù)據(jù)綁定的形式,當(dāng)數(shù)據(jù)變化時(shí)視圖自動(dòng)更新。
通過這個(gè)簡單的例子來看:
<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>
框架首先將邏輯層數(shù)據(jù)中的 name 與視圖層的 name 進(jìn)行了綁定,所以打開頁面的時(shí)候會(huì)顯示 HelloCML; 當(dāng)點(diǎn)擊按鈕的時(shí)候,視圖層會(huì)發(fā)送 changeName 的事件給邏輯層,邏輯層找到并執(zhí)行對(duì)應(yīng)的事件處理函數(shù); 回調(diào)函數(shù)觸發(fā)后,邏輯層執(zhí)行數(shù)據(jù)賦值的操作,將 data 中的 name 從 CML 變?yōu)?CML,因?yàn)樵摂?shù)據(jù)和視圖層已經(jīng)綁定了,從而視圖層會(huì)自動(dòng)改變?yōu)?Hello CML!。
每個(gè) CML 實(shí)例在被創(chuàng)建時(shí)都要經(jīng)過一系列的初始化過程——例如,需要設(shè)置數(shù)據(jù)監(jiān)聽、編譯模板、將實(shí)例掛載到 節(jié)點(diǎn) 并在數(shù)據(jù)變化時(shí)更新 節(jié)點(diǎn) 等。同時(shí)在這個(gè)過程中也會(huì)運(yùn)行一些叫做生命周期鉤子的函數(shù),這給開發(fā)者在不同階段添加自己的代碼的機(jī)會(huì)。
chameleon 為組件和 頁面 提供了一系列生命周期事件,保障應(yīng)用有序執(zhí)行。 如果你想使用某個(gè)端特定的生命周期,請(qǐng)從業(yè)務(wù)出發(fā)使用多態(tài)接口接收特定的生命周期事件回調(diào)。
鉤子 | 執(zhí)行時(shí)機(jī) | 詳細(xì) |
---|---|---|
beforeCreate | 實(shí)例初始化之后,數(shù)據(jù)和方法掛在到實(shí)例之前 | 頁面會(huì)在該生命周期中返回傳入當(dāng)前頁面的參數(shù)對(duì)象 |
created | 數(shù)據(jù)及方法掛載完成 | 頁面會(huì)在該生命周期中返回傳入當(dāng)前頁面的參數(shù)對(duì)象 |
beforeMount | 開始掛載已經(jīng)編譯完成的cml到對(duì)應(yīng)的節(jié)點(diǎn)時(shí) | 在頁面會(huì)在該生命周期中返回傳入當(dāng)前頁面的參數(shù)對(duì)象 |
mounted | cml模板編譯完成,且渲染到dom中完成 | |
beforeDestroy | 實(shí)例銷毀之前 | |
destroyed | 實(shí)例銷毀后 |
chameleon-runtime@0.2.0 開始支持
頁面顯示/切入前臺(tái)時(shí)觸發(fā)
chameleon-runtime@0.2.0 開始支持
頁面隱藏/切入后臺(tái)時(shí)觸發(fā)
** 注意:頁面不會(huì)在 onShow、onHide 回調(diào)函數(shù)中返回頁面參數(shù) **
參數(shù)說明
名稱 | 類型 | 說明 |
---|---|---|
res | Object | 僅有頁面在該生命周期回調(diào)函數(shù)中會(huì) 返回對(duì)象res: res = { query } query 是打開當(dāng)前頁面路徑中的參數(shù) |
參數(shù)說明
名稱 | 類型 | 說明 |
---|---|---|
res | Object | 僅有頁面在該生命周期回調(diào)函數(shù)中會(huì) 返回對(duì)象res: res = { query } query 是打開當(dāng)前頁面路徑中的參數(shù) |
參數(shù)說明
名稱 | 類型 | 說明 |
---|---|---|
res | Object | 僅有頁面在該生命周期回調(diào)函數(shù)中會(huì) 返回對(duì)象res: res = { query } query 是打開當(dāng)前頁面路徑中的參數(shù) |
<template>
<view> </view>
</template>
<script>
class Index {
beforeCreate(query) {
// data數(shù)據(jù)掛載到this根節(jié)點(diǎn)上之前,以及methods所有方法掛載到實(shí)例根節(jié)點(diǎn)之前
// 注意:只用頁面的 beforeCreate鉤子 會(huì)返回頁面query
console.log('App beforeCreate: 打開當(dāng)前頁面路徑中的參數(shù)是 ', query);
}
created() {
// data,methods里面的這些events掛載完成
console.log('App created');
}
beforeMount() {
// 開始掛載已經(jīng)編譯完成的cml到對(duì)應(yīng)的節(jié)點(diǎn)時(shí)
console.log('App beforeMount');
}
mounted() {
// cml模板編譯完成,且渲染到dom中完成,在整個(gè)生命周期中只執(zhí)行一次
console.log('App mounted');
}
beforeDestroy() {
// 實(shí)例銷毀前
console.log('App beforeDestroy');
}
destroyed() {
// 實(shí)例銷毀后
console.log('App destroyed');
}
}
export default new Index();
</script>
CML 在 *.[web|weex|wx].cml 文件中支持生命周期的多態(tài),可以針對(duì)不同的平臺(tái)添加專屬鉤子函數(shù)。
假設(shè)有一個(gè)頁面home.cml,需要使用小程序頁面分享生命周期微信端 onShareAppMessage,可以如下實(shí)現(xiàn):
<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>
<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>
對(duì)于模板內(nèi)任何復(fù)雜邏輯,你都應(yīng)當(dāng)使用計(jì)算屬性
<template>
<view>
<text>Original message: "{{ message }}"</text>
<text>Computed reversed message: "{{ reversedMessage }}"</text>
</view>
</template>
<script>
class Index {
data = {
message: 'Hello',
};
computed = {
// 計(jì)算屬性的 getter
reversedMessage: function() {
return this.message
.split('')
.reverse()
.join('');
},
};
}
export default new Index();
</script>
結(jié)果:
Original message: "Hello"
Computed reversed message: "olleH"
這里我們聲明了一個(gè)計(jì)算屬性 reversedMessage。 我們提供的函數(shù)將用作屬性 reversedMessage 的 getter 函數(shù),當(dāng) message 發(fā)生改變時(shí),reversedMessage 也會(huì)更新
提供了一種更通用的方式來觀察和響應(yīng)實(shí)例上的數(shù)據(jù)變動(dòng)
<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 選項(xiàng)之外,你還可以使用命令式的 this.$watch API。
但是,上面代碼是命令式且重復(fù)的。將它與計(jì)算屬性的版本進(jìn)行比較:
<script>
class Index {
data = {
firstName: 'Foo',
lastName: 'Bar',
};
computed = {
fullName: function() {
return this.firstName + ' ' + this.lastName;
},
};
}
</script>
所以,不要濫用 watch ~
CML 框架提供了豐富的多態(tài)接口,可以調(diào)起各端提供的原生能力,如系統(tǒng)信息、元素節(jié)點(diǎn)信息、動(dòng)畫效果、本地存儲(chǔ)、網(wǎng)絡(luò)請(qǐng)求、地理位置等。請(qǐng)參考API 文檔。
代碼示例
import cml from 'chameleon-api';
cml.showToast({
message: 'Hello world!',
duration: 1000,
});
通常,在 CML API 有以下幾種類型:
大多數(shù) API 都是異步 API,如 cml.get 等。這類 API 接口通常都接受一個(gè) Object 類型的參數(shù),返回 Promise ,對(duì)應(yīng)請(qǐng)求成功和失敗回調(diào),支持 then 鏈?zhǔn)秸{(diào)用。
代碼示例
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,
});
},
);
代碼示例
import a from 'a.js';
export { a };
代碼示例
// store.js
import createStore from 'chameleon-store';
const store = createStore({ state, mutations, actions, getters, modules });
export default store;
更多建議: