邏輯層

2020-05-14 14:20 更新

邏輯層負責反饋用戶對界面操作的處理中心。

邏輯層是終端開發(fā)的“靈魂”。

而 VM 對象 是邏輯層規(guī)范的輸入口

VM 對象

字段名類型說明
propsObject聲明當前組件可接收數據屬性
props = { type, default }
type為數據類型,default為數據默認值
dataObjectCML模板可直接使用的響應數據,是連接視圖層的樞紐
methodsObject處理業(yè)務邏輯與交互邏輯的方法
watchObject偵聽屬性,監(jiān)聽數據的變化,觸發(fā)相應操作
computedObjectCML模板可直接使用的計算屬性數據,也是連接視圖層的樞紐
beforeCreateFunction例初始化之后,數據和方法掛在到實例之前 一個頁面只會返回一次
createdFunction數據及方法掛載完成
beforeMountFunction開始掛載已經編譯完成的cml到對應的節(jié)點時
mountedFunctioncml模板編譯完成,且渲染到dom中完成
beforeDestroyFunction實例銷毀之前
destroyedFunction實例銷毀后

響應式數據綁定系統(tǒng)

響應式數據綁定意味著開發(fā)者只需關心邏輯處理,通過數據綁定的形式,當數據變化時視圖自動更新。

通過這個簡單的例子來看:

<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; 當點擊按鈕的時候,視圖層會發(fā)送 changeName 的事件給邏輯層,邏輯層找到并執(zhí)行對應的事件處理函數; 回調函數觸發(fā)后,邏輯層執(zhí)行數據賦值的操作,將 data 中的 name 從 CML 變?yōu)?CML,因為該數據和視圖層已經綁定了,從而視圖層會自動改變?yōu)?Hello CML!。

生命周期

每個 CML 實例在被創(chuàng)建時都要經過一系列的初始化過程——例如,需要設置數據監(jiān)聽、編譯模板、將實例掛載到 節(jié)點 并在數據變化時更新 節(jié)點 等。同時在這個過程中也會運行一些叫做生命周期鉤子的函數,這給開發(fā)者在不同階段添加自己的代碼的機會。

chameleon 為組件和 頁面 提供了一系列生命周期事件,保障應用有序執(zhí)行。 如果你想使用某個端特定的生命周期,請從業(yè)務出發(fā)使用多態(tài)接口接收特定的生命周期事件回調。

鉤子執(zhí)行時機詳細
beforeCreate實例初始化之后,數據和方法掛在到實例之前頁面會在該生命周期中返回傳入當前頁面的參數對象
created數據及方法掛載完成頁面會在該生命周期中返回傳入當前頁面的參數對象
beforeMount開始掛載已經編譯完成的cml到對應的節(jié)點時在頁面會在該生命周期中返回傳入當前頁面的參數對象
mountedcml模板編譯完成,且渲染到dom中完成
beforeDestroy實例銷毀之前
destroyed實例銷毀后

頁面 Page 獨有生命周期

onShow()

chameleon-runtime@0.2.0 開始支持

頁面顯示/切入前臺時觸發(fā)

onHide()

chameleon-runtime@0.2.0 開始支持

頁面隱藏/切入后臺時觸發(fā)

** 注意:頁面不會在 onShow、onHide 回調函數中返回頁面參數 **

生命周期回調函數

beforeCreate(Object res)

參數說明

名稱類型說明
resObject僅有頁面在該生命周期回調函數中會
返回對象res:
res = { query } query 是打開當前頁面路徑中的參數

created(Object res)

參數說明

名稱類型說明
resObject僅有頁面在該生命周期回調函數中會
返回對象res:
res = { query } query 是打開當前頁面路徑中的參數

beforeMount(Object res)

參數說明

名稱類型說明
resObject僅有頁面在該生命周期回調函數中會
返回對象res:
res = { query } query 是打開當前頁面路徑中的參數

鉤子示例

<template>
  <view> </view>
</template>
<script>
class Index {
  beforeCreate(query) {
    // data數據掛載到this根節(jié)點上之前,以及methods所有方法掛載到實例根節(jié)點之前
    // 注意:只用頁面的 beforeCreate鉤子 會返回頁面query
    console.log('App beforeCreate: 打開當前頁面路徑中的參數是 ', query);
  }
  created() {
    // data,methods里面的這些events掛載完成
    console.log('App created');
  }
  beforeMount() {
    // 開始掛載已經編譯完成的cml到對應的節(jié)點時
    console.log('App beforeMount');
  }
  mounted() {
    // cml模板編譯完成,且渲染到dom中完成,在整個生命周期中只執(zhí)行一次
    console.log('App mounted');
  }
  beforeDestroy() {
    // 實例銷毀前
    console.log('App beforeDestroy');
  }
  destroyed() {
    // 實例銷毀后
    console.log('App destroyed');
  }
}
export default new Index();
</script>

生命周期多態(tài)

CML 在 *.[web|weex|wx].cml 文件中支持生命周期的多態(tài),可以針對不同的平臺添加專屬鉤子函數。

假設有一個頁面home.cml,需要使用小程序頁面分享生命周期微信端 onShareAppMessage,可以如下實現:

  1. 項目根目錄執(zhí)行 cml init component,選擇 multimode-interface 多態(tài)接口,輸入 interface name: lifecycleInterface,自動生成src/components/lifecycleInterface 
  2. 在src/components/lifecycleInterface/lifecycleInterface.cml多態(tài)接口中,添加如下代碼:
<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>
  1. 在 home.cml 文件,使methods合并lifecycleInterface多態(tài)方法
<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 發(fā)生改變時,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 框架提供了豐富的多態(tài)接口,可以調起各端提供的原生能力,如系統(tǒng)信息、元素節(jié)點信息、動畫效果、本地存儲、網絡請求、地理位置等。請參考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;


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號