我们用5分钟写了一个跨多端项目
cml 作為真正讓一套代碼運行多端的框架,提供標準的MVVM模式,統一開發各類終端。同時,擁有各端獨立的運行時框架(runtime)、數據管理(store)、組件庫(ui)、接口(api)。此外,cml在跨端能力加強、能力統一、表現一致等方面做了許多工作。
今天,為了讓大家的項目優雅升級,快速接入,給你帶來一份豐盛的cml遷移指南~
源碼地址:https://github.com/jalonjs/cml-first-demo
目錄結構
和微信小程序一樣,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 文件對項目進行配置。
配置示例:
{ \u0026quot;miniprogramRoot\u0026quot;: \u0026quot;./src\u0026quot;, \u0026quot;debugOptions\u0026quot;: {}}小程序 —— 全局配置
小程序根目錄下的 app.json 文件用來對微信小程序進行全局配置,決定頁面文件的路徑、窗口表現、設置網絡超時時間、設置多 tab 等
配置示例:
{ \u0026quot;pages\u0026quot;: [\u0026quot;pages/index/index\u0026quot;, \u0026quot;pages/logs/index\u0026quot;], \u0026quot;window\u0026quot;: { \u0026quot;navigationBarTitleText\u0026quot;: \u0026quot;Demo\u0026quot; }, \u0026quot;networkTimeout\u0026quot;: { \u0026quot;request\u0026quot;: 10000, \u0026quot;downloadFile\u0026quot;: 10000 }}小程序 —— 頁面配置
每一個小程序頁面也可以使用 .json 文件來對本頁面的窗口表現進行配置。
頁面的配置只能設置 app.json 中部分 window 配置項的內容,頁面中配置項會覆蓋 app.json 的 window 中相同的配置項。
配置示例:
{ \u0026quot;navigationBarBackgroundColor\u0026quot;: \u0026quot;#ffffff\u0026quot;, \u0026quot;navigationBarTextStyle\u0026quot;: \u0026quot;black\u0026quot;, \u0026quot;navigationBarTitleText\u0026quot;: \u0026quot;微信接口功能演示\u0026quot;, \u0026quot;backgroundColor\u0026quot;: \u0026quot;#eeeeee\u0026quot;, \u0026quot;backgroundTextStyle\u0026quot;: \u0026quot;light\u0026quot;}同樣,在 cml項目里面,分為以下幾種配置方案。
cml —— 項目配置
chameleon.config.js 為項目的配置文件,你可以定制化構建,比如是否帶hash,是否\u0008壓縮等等。
配置示例:
// 設置靜態資源的線上路徑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 文件的 \u0026lt;script cml-type=\u0026quot;json\u0026quot; /\u0026gt; 用來對 cml應用 進行全局配置,具有 跨端配置 和 差異化 的能力
配置示例:
\u0026lt;script cml-type=\u0026quot;json\u0026quot;\u0026gt;{ \u0026quot;base\u0026quot;: { \u0026quot;window\u0026quot;: { \u0026quot;navigationBarTitleText\u0026quot;: \u0026quot;各個端共同title\u0026quot;, }, \u0026quot;permission\u0026quot;: { \u0026quot;scope.userLocation\u0026quot;: { \u0026quot;desc\u0026quot;: \u0026quot;你的位置信息將用于小程序位置接口的效果展示\u0026quot; } } }, \u0026quot;wx\u0026quot;: { \u0026quot;window\u0026quot;: { \u0026quot;backgroundTextStyle\u0026quot;:\u0026quot;light\u0026quot;, \u0026quot;navigationBarBackgroundColor\u0026quot;: \u0026quot;#fff\u0026quot;, \u0026quot;navigationBarTitleText\u0026quot;: \u0026quot;差異化 title\u0026quot;, \u0026quot;navigationBarTextStyle\u0026quot;:\u0026quot;black\u0026quot; } }, \u0026quot;baidu\u0026quot;: { \u0026quot;window\u0026quot;: { \u0026quot;backgroundTextStyle\u0026quot;: \u0026quot;light\u0026quot; } }, \u0026quot;alipay\u0026quot;: { \u0026quot;window\u0026quot;: { \u0026quot;defaultTitle\u0026quot;: \u0026quot;Chameleon\u0026quot; } }}\u0026lt;/script\u0026gt;cml —— 頁面/組件配置
通過 usingComponents 配置 組件路徑 注冊引用的組件。
配置示例:
\u0026lt;script cml-type=\u0026quot;json\u0026quot;\u0026gt;{ \u0026quot;base\u0026quot;: { \u0026quot;usingComponents\u0026quot;: { \u0026quot;navi\u0026quot;: \u0026quot;/components/navi/navi\u0026quot;, \u0026quot;navi-npm\u0026quot;: \u0026quot;cml-test-ui/navi/navi\u0026quot; } }, \u0026quot;wx\u0026quot;: { }, \u0026quot;alipay\u0026quot;: { }, \u0026quot;baidu\u0026quot;: { }, \u0026quot;web\u0026quot;: { }, \u0026quot;weex\u0026quot;: { }}\u0026lt;/script\u0026gt;如何使用路由能力?
小程序配置路由
app.json配置項列表的 pages 字段用于指定小程序由哪些頁面組成,每一項都對應一個頁面的 路徑+文件名 信息。
數組的第一項代表小程序的初始頁面(首頁)。新增/減少頁面,需要對 pages 數組進行修改。
如果項目有 pages/index/index.wxml、pages/logs/logs.wxml 兩個頁面,則需要在 app.json 中寫
{ \u0026quot;pages\u0026quot;: [\u0026quot;pages/index/index\u0026quot;, \u0026quot;pages/logs/logs\u0026quot;]}cml配置路由
src/router.config.json是路由的配置文件,cml 內置了一套各端統一的路由管理方式。相應有 cml 路由配置映射如下:
{ \u0026quot;mode\u0026quot;: \u0026quot;history\u0026quot;, \u0026quot;domain\u0026quot;: \u0026quot;https://www.chameleon.com\u0026quot;, \u0026quot;routes\u0026quot;:[ { \u0026quot;url\u0026quot;: \u0026quot;/cml/h5/index\u0026quot;, \u0026quot;path\u0026quot;: \u0026quot;/pages/index/index\u0026quot;, \u0026quot;mock\u0026quot;: \u0026quot;index.php\u0026quot; }, { \u0026quot;url\u0026quot;: \u0026quot;/cml/h5/logs\u0026quot;, \u0026quot;path\u0026quot;: \u0026quot;pages/logs/logs\u0026quot;, \u0026quot;mock\u0026quot;: \u0026quot;logs.php\u0026quot; } ]}文件名不需要寫文件后綴,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注冊程序
示例代碼:
\u0026lt;script\u0026gt;import store from '../store/index.js'import routerConfig from '../router.config.json';class App { data = { store, routerConfig } created(res) { }}export default new App();\u0026lt;/script\u0026gt;細心的你會發現,
小程序中app.json app.js app.wxss和 src/app/app.cml的對應關系如下:
小程序注冊頁面
在小程序項目里面,Page(Object) 函數用來注冊一個頁面。接受一個 Object 類型參數,其指定頁面的初始數據、生命周期回調、事件處理函數等。
示例代碼:
// index.jsPage({ data: { text: 'This is page data.' }, changeText: function(e) { // sent data change to view this.setData({ text: 'CML' }) }})cml注冊頁面
示例代碼:
\u0026lt;script\u0026gt;class Index { data = { text: 'Chameleon' } methods = { changeText: function(e) { // sent data change to view this.text = 'CML'; } } computed = {} watch = {}};export default new Index();\u0026lt;/script\u0026gt;小程序注冊組件
在小程序項目里面,
Component(Object) 構造器可用于定義組件,調用 Component 構造器時可以指定組件的屬性、數據、方法等。
示例代碼:
Component({ properties: { myProperty: { // 屬性名 type: String, // 類型(必填) value: '' // 屬性初始值(可選) }, myProperty2: String // 簡化的定義方式 }, data: { text: '' }, // 私有數據,可用于模板渲染 // 生命周期函數,可以為函數,或一個在methods段中定義的方法名 attached() { }, ready() { }, methods: { onMyButtonTap() { this.setData({ // 更新屬性和數據的方法與更新頁面數據的方法類似 text: 'wx' }) } }})cml注冊組件
示例代碼:
\u0026lt;script\u0026gt;class MyComponent { props = { myProperty: { // 屬性名 type: String, // 類型(必填) default: '' // 屬性初始值(可選) }, myProperty2: String // 簡化的定義方式 } data = { text: '' } // 私有數據,可用于模板渲染 beforeMount() {} mounted() {} methods = { onMyButtonTap() { this.text = 'cml' } } computed = {} watch = {}};export default new MyComponent();\u0026lt;/script\u0026gt;如何聲明生命周期
統一各端應用生命周期的定義,是跨端框架的重要組成,也是遷移的必經之路。
小程序聲明生命周期
可以在 App(Object)、Page(Object)、Component(Object) 傳入Object參數,其指定小程序的生命周期回調等。
代碼示例:
// index.jsPage({ 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 文件 \u0026lt;script /\u0026gt; 代碼塊返回的對象實例,其指定生命周期回調
示例代碼:
\u0026lt;script\u0026gt;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();\u0026lt;/script\u0026gt;App 生命周期映射
小程序 app.js中的生命周期 -\u0026gt; cml src/app/app.cml
Page 生命周期映射
小程序 Page()中的生命周期 -\u0026gt; cml src/pages/mypage/mypage.cml
Component 生命周期映射
小程序 Component()中的生命周期 -\u0026gt; cml src/components/mycomponent/mycomponent.cml
生命周期總結
每個 cml 實例(App、Page、Component)在被創建時都要經過一系列的初始化過程。
例如,需要設置數據監聽、編譯模板、將實例掛載到 \u0008CML節點 并在數據變化時更新 \u0008CML節點 等。同時在這個過程中也會運行一些叫做生命周期鉤子的函數,這給開發者在不同階段添加自己的代碼的機會。
cml 為App、頁面Page、組件Component 提供了一系列生命周期事件,保障應用有序執行。
另外,如果你想使用某個端特定的生命周期,你可以從業務出發使用生命周期多態。
數據如何響應到視圖
如今,雙向數據綁定\u0026amp;單向數據流 已深入開發者日常,MVMM開發模式算是框架標配。
數據綁定、條件渲染、列表渲染 是如何書寫的呢?
示例代碼
小程序使用數據響應
\u0026lt;!--wxml--\u0026gt;\u0026lt;view class=\u0026quot;scroller-wrap\u0026quot;\u0026gt; \u0026lt;!--數據綁定--\u0026gt; \u0026lt;view\u0026gt;{{message}}\u0026lt;/view\u0026gt; \u0026lt;!--條件渲染--\u0026gt; \u0026lt;view wx:if=\u0026quot;{{view == 'WEBVIEW'}}\u0026quot;\u0026gt;WEBVIEW\u0026lt;/view\u0026gt; \u0026lt;view wx:elif=\u0026quot;{{view == 'APP'}}\u0026quot;\u0026gt;APP\u0026lt;/view\u0026gt; \u0026lt;view wx:else=\u0026quot;{{view == 'MINA'}}\u0026quot;\u0026gt;MINA\u0026lt;/view\u0026gt; \u0026lt;!--列表渲染--\u0026gt; \u0026lt;view wx:for=\u0026quot;{{array}}\u0026quot; wx:for-index=\u0026quot;index\u0026quot; wx:for-item=\u0026quot;item\u0026quot;\u0026gt;{{item}}\u0026lt;/view\u0026gt;\u0026lt;/view\u0026gt; // page.jsPage({ data: { message: 'Hello MINA!', view: 'MINA', array: [1, 2, 3, 4, 5] }, onLoad() { this.setData({ message: 'wx' }) }})cml使用數據響應
\u0026lt;template\u0026gt;\u0026lt;!--index.cml--\u0026gt;\u0026lt;view class=\u0026quot;scroller-wrap\u0026quot;\u0026gt; \u0026lt;!--數據綁定--\u0026gt; \u0026lt;view\u0026gt;{{message}}\u0026lt;/view\u0026gt; \u0026lt;!--條件渲染--\u0026gt; \u0026lt;view c-if=\u0026quot;{{view == 'WEBVIEW'}}\u0026quot;\u0026gt;WEBVIEW\u0026lt;/view\u0026gt; \u0026lt;view c-else-if=\u0026quot;{{view == 'APP'}}\u0026quot;\u0026gt;APP\u0026lt;/view\u0026gt; \u0026lt;view c-else=\u0026quot;{{view == 'MINA'}}\u0026quot;\u0026gt;MINA\u0026lt;/view\u0026gt; \u0026lt;!--列表渲染--\u0026gt; \u0026lt;view c-for=\u0026quot;{{array}}\u0026quot; c-for-index=\u0026quot;index\u0026quot; c-for-item=\u0026quot;item\u0026quot;\u0026gt;{{item}}\u0026lt;/view\u0026gt;\u0026lt;/view\u0026gt;\u0026lt;/template\u0026gt;\u0026lt;script\u0026gt;class Index { data = { message: 'Hello MINA!', view: 'MINA', array: [1, 2, 3, 4, 5] } beforeCreate () { this.message = 'cml' }};export default new Index();\u0026lt;/script\u0026gt;數據響應總結
cml運行時框架 提供了跨端響應式數據綁定系統(Data binding),當做數據修改的時候,只需要在邏輯層修改數據,視圖層就會做相應的更新。
只需要將 view\u0026lt;--\u0026gt;model 交互部分邏輯,作簡單遷移,便可使它成為跨多端的數據響應系統。
事件交互
cml 支持一些基礎的事件,保障各端效果(類型、綁定、事件對象)一致運行。
示例代碼
小程序使用事件
\u0026lt;!--wxml--\u0026gt;\u0026lt;view id=\u0026quot;tapTest\u0026quot; data-hi=\u0026quot;WeChat\u0026quot; bindtap=\u0026quot;tapName\u0026quot;\u0026gt;Click me!\u0026lt;/view\u0026gt; // page.jsPage({ tapName(event) { console.log(event) }})cml使用事件
\u0026lt;template\u0026gt; \u0026lt;view id=\u0026quot;tapTest\u0026quot; data-hi=\u0026quot;WeChat\u0026quot; c-bind:tap=\u0026quot;tapName\u0026quot;\u0026gt; \u0026lt;text\u0026gt;Click me!\u0026lt;/text\u0026gt; \u0026lt;/view\u0026gt;\u0026lt;/template\u0026gt;\u0026lt;script\u0026gt;class Index { methods = { tapName(e) { // 打印事件對象 console.log('事件對象:', e); } }}export default new Index();\u0026lt;/script\u0026gt;事件使用總結
同時,還支持自定義事件,用于父子組件之間的通信。
另外,如果你想要使用某個端特定的事件,cml 并不會限制你的自由發揮,你可以從業務出發使用 組件多態 或者 接口多態 差異化實現功能。
布局和外觀
各端描述 布局和外觀 的層疊樣式表(CSS)實現存在差異,包括不限于 布局、盒模型、定位、文本。
所以, cml 框架內置跨端一致性基礎樣式能力。
并且,定義了用于描述頁面的樣式規范CMSS(Chameleon Style Sheet)。
如何導入外部樣式
使用 @import 語句可以導入外聯樣式表,@import 后跟需要導入的外聯樣式表的相對路徑,用 ; 表示語句結束。
小程序導入外部樣式
示例代碼:
/** common.wxss **/.small-p { padding:5px;} /** app.wxss **/@import \u0026quot;common.wxss\u0026quot;;.middle-p { padding:15px;}cml導入外部樣式
詳細文檔:https://cmljs.org/doc/api/runtime/@import.html
示例代碼:
/** common.css **/.small-p { padding: 5px;} \u0026lt;!-- app.cml --\u0026gt;\u0026lt;style\u0026gt; @import './common.css'; .middle-p { padding:15 cpx; }\u0026lt;/style\u0026gt;樣式使用總結
同時,為了統一多端尺寸單位,呈現效果一致,同時頁面響應式布局,cml 項目統一采用 cpx 作為尺寸單位,規定以屏幕750px(占滿屏幕)視覺稿作為標準。
而且,各端樣式表擁有的能力不盡相同,是項目遷移的主要陣地之一。
另外,如果你想要使用某個端特定的樣式能力,cml 并不會限制你的自由發揮,你可以從業務出發使用樣式多態
注意:由于chameleon應用是 跨多端web native 小程序框架,如果需要跨native,必須使用 flexbox 進行樣式布局!!!
組件
cml 項目一切皆組件。組件(Component)是視圖的基本組成單元。
框架為開發者提供了一系列基礎組件,開發者可以通過組合這些基礎組件進行快速開發。
如:
\u0026lt;template\u0026gt; \u0026lt;view\u0026gt; \u0026lt;view\u0026gt;view 基礎組件\u0026lt;/view\u0026gt; \u0026lt;text\u0026gt;text 基礎組件\u0026lt;/text\u0026gt; \u0026lt;/view\u0026gt;\u0026lt;/template\u0026gt;同時,cml 支持簡潔的組件化編程。
自定義組件
開發者可以將頁面內的功能模塊抽象成自定義組件,以便在不同的頁面中重復使用。自定義組件在使用時與基礎組件非常相似。
如何創建自定義組件
小程序創建自定義組件
代碼示例:
Component({ properties: { // 這里定義了innerText屬性,屬性值可以在組件使用時指定 innerText: { type: String, value: 'default value', } }, data: { // 這里是一些組件內部數據 someData: {} }, methods: { // 這里是一個自定義方法 customMethod() {} }})cml創建自定義組件
示例代碼
\u0026lt;script\u0026gt;class MyComponent { props = { // 這里定義了innerText屬性,屬性值可以在組件使用時指定 innerText: { type: String, value: 'default value', } } data = { // 這里是一些組件內部數據 someData: {} } methods = { // 這里是一個自定義方法 customMethod() {} } computed = {} watch = {}};export default new MyComponent();\u0026lt;/script\u0026gt;如何使用自定義組件
使用已注冊的自定義組件前,首先要進行引用聲明。此時需要提供每個自定義組件的標簽名和對應的自定義組件文件路徑。
代碼示例:
在 page.json 中進行引用聲明
{ \u0026quot;usingComponents\u0026quot;: { \u0026quot;component-tag-name\u0026quot;: \u0026quot;path/to/the/custom/component\u0026quot; }}在 page.wxml 中使用
\u0026lt;view\u0026gt; \u0026lt;!-- 以下是對一個自定義組件的引用 --\u0026gt; \u0026lt;component-tag-name inner-text=\u0026quot;Some text\u0026quot;\u0026gt;\u0026lt;/component-tag-name\u0026gt;\u0026lt;/view\u0026gt;cml使用自定義組件
代碼示例:
在 page.cml中\u0026lt;script cml-type='json' /\u0026gt;進行引用聲明
\u0026lt;script cml-type=\u0026quot;json\u0026quot;\u0026gt;{ \u0026quot;base\u0026quot;: { \u0026quot;usingComponents\u0026quot;: { \u0026quot;component-tag-name\u0026quot;: \u0026quot;path/to/the/custom/component\u0026quot; } }}\u0026lt;/script\u0026gt;在 page.cml中\u0026lt;template /\u0026gt;使用
\u0026lt;template\u0026gt;\u0026lt;view\u0026gt; \u0026lt;!-- 以下是對一個自定義組件的引用 --\u0026gt; \u0026lt;component-tag-name inner-text=\u0026quot;Some text\u0026quot;\u0026gt;\u0026lt;/component-tag-name\u0026gt;\u0026lt;/view\u0026gt;\u0026lt;/template\u0026gt;如何實現父子組件事件通信
事件系統是組件間通信的主要方式之一。自定義組件可以觸發任意的事件,引用組件的頁面可以監聽這些事件。
小程序組件通信
代碼示例:
\u0026lt;!-- 頁面 page.wxml --\u0026gt;\u0026lt;view\u0026gt; \u0026lt;my-component bindcustomevent=\u0026quot;onMyEvent\u0026quot;\u0026gt;\u0026lt;/my-component\u0026gt;\u0026lt;/view\u0026gt; // 頁面 page.jsPage({ methods: { onMyEvent(e) { console.log(e.detail) // 自定義組件觸發事件時提供的detail對象 } }}) \u0026lt;!-- 組件 my-component.wxml --\u0026gt;\u0026lt;view\u0026gt; \u0026lt;button bindtap=\u0026quot;onTap\u0026quot;\u0026gt;點擊這個按鈕將觸發“myevent”事件\u0026lt;/button\u0026gt;\u0026lt;/view\u0026gt; // 組件 my-component.jsComponent({ methods: { onTap() { this.triggerEvent('customevent', {}) // 觸發 自定義組件事件 } }})cml組件通信
代碼示例:
\u0026lt;!-- 頁面 page.cml --\u0026gt;\u0026lt;template\u0026gt; \u0026lt;view\u0026gt; \u0026lt;my-component c-bind:customevent=\u0026quot;onMyEvent\u0026quot;\u0026gt;\u0026lt;/my-component\u0026gt; \u0026lt;/view\u0026gt;\u0026lt;/template\u0026gt;\u0026lt;script\u0026gt;class Index { methods = { // 這里是一個自定義方法 onMyEvent(e) { console.log(e.detail) // 自定義組件觸發事件時提供的detail對象 } }};export default new Index();\u0026lt;/script\u0026gt;\u0026lt;script cml-type=\u0026quot;json\u0026quot;\u0026gt;{ \u0026quot;base\u0026quot;: { \u0026quot;usingComponents\u0026quot;: { \u0026quot;my-component\u0026quot;: \u0026quot;path/to/the/custom/component\u0026quot; } }}\u0026lt;/script\u0026gt; \u0026lt;!-- 頁面 path/to/the/custom/component.cml --\u0026gt;\u0026lt;template\u0026gt; \u0026lt;view\u0026gt; \u0026lt;button c-bind:tap=\u0026quot;onTap\u0026quot;\u0026gt;點擊這個按鈕將觸發“myevent”事件\u0026lt;/button\u0026gt; \u0026lt;/view\u0026gt;\u0026lt;/template\u0026gt;\u0026lt;script\u0026gt;class MyComponent { methods = { // 這里是一個自定義方法 onTap() { this.$cmlEmit('customevent', {}) // 觸發 自定義組件事件 } }};export default new MyComponent();\u0026lt;/script\u0026gt;\u0026lt;script cml-type=\u0026quot;json\u0026quot;\u0026gt;{}\u0026lt;/script\u0026gt;組件使用總結
和小程序一樣,cml框架 提供了大量內置組件和擴展組件,抹平多端差異,便于開發者通過組合這些組件,創建出強大的應用程序。
擴展組件需要額外引入。如:
\u0026lt;script cml-type=\u0026quot;json\u0026quot;\u0026gt;{ \u0026quot;base\u0026quot;: { \u0026quot;usingComponents\u0026quot;: { \u0026quot;c-dialog\u0026quot;: \u0026quot;cml-ui/components/c-dialog/c-dialog\u0026quot; } }}\u0026lt;/script\u0026gt;在執行 cml build 構建打包時,cml 框架 會按需打包引用的內置組件和擴展組件,為代碼瘦身。
內置組件和擴展組件都是支持跨多端的,對于一些沒有提供的某個端的組件,可以通過組件多態來實現。
如果希望使用小程序端的原生組件,那么可以在原生標簽前加上 origin-*,cml框架會渲染原生組件參考
注意:origin-* 只能在灰度區文件中使用!!
如在 map.wx.cml 文件中使用原生地圖組件 \u0026lt;map/\u0026gt;:
\u0026lt;!-- map.wx.cml --\u0026gt;\u0026lt;template\u0026gt; \u0026lt;origin-map id=\u0026quot;map\u0026quot; longitude=\u0026quot;113.324520\u0026quot; latitude=\u0026quot;23.099994\u0026quot; controls=\u0026quot;{{controls}}\u0026quot; bindcontroltap=\u0026quot;controltap\u0026quot; style=\u0026quot;width: 100%; height: 300px;\u0026quot; \u0026gt;\u0026lt;/origin-map\u0026gt;\u0026lt;/template\u0026gt;如何調用平臺接口能力
在小程序里面,可以通過微信原生 API,調起如獲取用戶信息,本地存儲,支付功能等。
示例代碼:
try { wx.setStorageSync('name', 'Hanks')} catch (e) { console.error(e)}同樣,在 cml 項目里面可以這樣調用:
示例代碼:
import cml from 'chameleon-api'cml.setStorage('name', 'Hanks').then((res)=\u0026gt;{ console.log(res)},function(e){ console.error(e)})接口使用總結
cml 框架提供了豐富的多態接口,可以調起各端提供的原生能力,如系統信息、元素節點信息、動畫效果、本地存儲、網絡請求、地理位置等。請參考 API 文檔。
chameleon-api提供的接口都是支持跨多端的,對于一些沒有提供的某個端的原生接口,可以通過接口多態來調用。
遷移實例
下面給出各端(vue、weex、小程序)遷移cml指南 以及 cml 導出組件到各端指南的具體遷移文檔:
如何遷移一個Vue項目到chameleon;
如何遷移一個Weex項目到chameleon;
如何遷移一個微信小程序到chameleon;
普通項目使用chameleon跨端dialog組件。
更多內容,請關注前端之巔。
總結
以上是生活随笔為你收集整理的我们用5分钟写了一个跨多端项目的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转载]历上最强的音乐播放器(jetAu
- 下一篇: 省掉bean自定义spring mvc注