遷移微信小程序項(xiàng)目到 CML

2020-05-14 14:20 更新

遷移原則:

以小邏輯塊為單位,對(duì)照老代碼,以 cml 語(yǔ)法重寫(xiě),報(bào)錯(cuò)可修正

這樣可避免以下問(wèn)題:

1、大塊邏輯遷移會(huì)導(dǎo)致報(bào)錯(cuò)無(wú)法追查

2、直接 copy 會(huì)導(dǎo)致語(yǔ)法隱藏 bug 不可控(雖然 ide 沒(méi)有問(wèn)題,但真機(jī)調(diào)試出問(wèn)題)

請(qǐng)盡量按照 cml 語(yǔ)法重寫(xiě)遷移,避免語(yǔ)法糾錯(cuò)浪費(fèi)時(shí)間

小程序多文件結(jié)構(gòu) -> cml 單文件頁(yè)面

小程序CML
xxx.wxml<template></template>
xxx.js<script></script>
xxx.wxss<style></style>
xxx.json<script cml-type="json"></script>

項(xiàng)目初始化

cml init project

初始化后,CML 項(xiàng)目如下:

依具體情況配置構(gòu)建平臺(tái)和配置平臺(tái)基礎(chǔ)樣式。

可修改 chameleon.config.js 的 platforms 和 baseStyle 字段,如下:

假設(shè)有下面 ???? 結(jié)構(gòu)的小程序項(xiàng)目

pages 下包含各個(gè)頁(yè)面,components 下包含各個(gè)組件代碼

遷移 app.js、app.json

小程序代碼配置微信應(yīng)用的配置

app.json

{
  "pages":[
    "pages/index1",
    "pages/index2",
    "pages/index3",
    "pages/index4",
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle":"black"
  }
}

遷移 app.json ———— 路由 pages 配置

以上小程序 app.json 中 pages 字段 -> src/router.config.json 中 path 字段

{
  "mode": "history",
  "domain": "https://www.chameleon.com",
  "routes":[
    {
      "url": "/cml/h5/index",
      "path": "/pages/index1/index1",
      "name": "首頁(yè)",
      "mock": "index.php"
    },
    {
      "url": "/cml/h5/inner-detail",
      "path": "/pages/index2/index2",
      "name": "首頁(yè)",
      "mock": "index.php"
    },
    {
      "url": "/cml/h5/inner-home",
      "path": "/pages/index3/index3",
      "name": "首頁(yè)",
      "mock": "index.php"
    },
    {
      "url": "/cml/h5/inner-my",
      "path": "/pages/index4/index4",
      "name": "首頁(yè)",
      "mock": "index.php"
    }
  ]
}

遷移 app.json ———— 其他配置

小程序 app.json 中 其他字段 -> src/app/app.cml 中配置


<script cml-type="json">
{
  "wx": {
    "window": {
      "backgroundTextStyle":"light",
      "navigationBarBackgroundColor": "#fff",
      "navigationBarTitleText": "Chameleon",
      "navigationBarTextStyle":"black"
    }
  }
}
</script>

遷移 app.js ———— 生命周期映射

小程序 app.js中的生命周期 -> src/app/app.cml

小程序CML
onLaunchbeforeCreate
onShowmounted
onHidedestroyed

總結(jié)

小程序中app.json app.js app.wxss和 src/app/app.cml的對(duì)應(yīng)關(guān)系如下

小程序 app.jsCML 項(xiàng)目 src/app/app.cml
app.js<script></script>
app.wxss<style></style>
app.json<script cml-type="json"></script>

遷移頁(yè)面

新建頁(yè)面

如上所述,小程序 app.json 中 pages 每個(gè)字段,對(duì)應(yīng)router.config.json中每條路由項(xiàng),對(duì)應(yīng) CML 項(xiàng)目的每個(gè)頁(yè)面

cml init page

輸入 index1

cml init page

輸入 index2
...

利用命令行命令,在src/pages中生成對(duì)應(yīng)的頁(yè)面

遷移頁(yè)面配置

假設(shè)小程序原有頁(yè)面 index1.json 配置如下

{
  "usingComponents": {
    "my-component1": "/components/comp1",
    "my-component2": "/components/comp2",
    "my-component3": "/components/comp3",
  },
  "navigationBarTitleText": "index",
  "backgroundTextStyle": "dark",
  "backgroundColor": "#E2E2E2"
}

修改src/pages/index1.cml 頁(yè)面配置,如下:

<script cml-type="json">
{
  "base": {
    "usingComponents": {
     	"my-component1": "/components/comp1",
        "my-component2": "/components/comp2",
        "my-component3": "/components/comp3",
    }
  },
  "wx": {
    "navigationBarTitleText": "index",
    "backgroundTextStyle": "dark",
    "backgroundColor": "#E2E2E2"
  }
}
</script>

其中:

  • base 代表各個(gè)小程序頁(yè)面的共有配置
  • wx 代表微信小程序端特有的配置

遷移頁(yè)面 ———— 生命周期映射

小程序CML
onLoadcreated
onShowonShow
onReadymounted
onHideonHide
onUnloaddestroyed
onShareAppMessage生命周期多態(tài)

總結(jié)

1 小程序頁(yè)面的遷移都要通過(guò) cml init page去初始化這個(gè)頁(yè)面

2 初始化的頁(yè)面要在src/router.config.json配置對(duì)應(yīng)的path字段

遷移組件

新建組件

如上,index1.json頁(yè)面中引用了組件 comp1 comp2 comp3;

組件分為:普通組件 和 多態(tài)組件

這里以普通組件為例,多態(tài)組件具體使用可以參考

cml init component
選擇 普通組件(normal-component)
輸入 comp1

cml init component
選擇 普通組件(normal-component)
輸入 comp2

.....

之后,會(huì)在 src/components下生成對(duì)應(yīng)的組件;

遷移組件 ———— 配置

同4.2 遷移頁(yè)面配置

遷移組件 ———— 生命周期映射

小程序CML
createdcreated
attachedbeforeMount
readymounted
detacheddestroyed

總結(jié)

1 小程序組件的遷移都要通過(guò) cml init component去初始化這個(gè)組件

2 初始化的組件要在使用該組件的地方配置 usingComponents字段

頁(yè)面&&組件遷移細(xì)節(jié)

template模板遷移

這里以 CML 語(yǔ)法為例:CML 基礎(chǔ)語(yǔ)法

#數(shù)據(jù)綁定、條件渲染、循環(huán)、事件綁定的遷移

假設(shè),原有小程序代碼,如下:

<view class="scroller-wrap">
  數(shù)據(jù)綁定
  <view>{{}}</view>
  條件渲染
  <view wx:if="{{condition1}}">wx:if</view>
  <view wx:elif="{{condition2}}">wx:elif</view>
  <view wx:else>wx:else</view>
  循環(huán)
  <view wx:for="{{array}}" wx:for-index="index" wx:for-item="item"></view>
  事件綁定
  <view id="tapTest" data-hi="WeChat" bindtap="tapName">Click me!</view>
</view>

那么,使用 CML 語(yǔ)法后:

<view>
  數(shù)據(jù)綁定
  <view>{{}}</view>
  條件渲染
  <view c-if="{{condition1}}">c-if</view>
  <view c-else-if="{{condition2}}">c-else-if</view>
  <view c-else>c-else</view>
  循環(huán)
  <view c-for="{{array}}" c-for-index="index" c-for-item="item"></view>
  事件綁定
  <view id="tapTest" data-hi="WeChat" bindtap="tapName">Click me!</view>
  CML 語(yǔ)法擴(kuò)展了事件綁定,支持直接在函數(shù)中傳參
  <view id="tapTest" bindtap="tapName('weChat',1,2,item)">Click me!</view>
</view>

小程序內(nèi)置組件 -> cml 內(nèi)置組件

小程序CML
viewview
texttext
blockblock
scroll-viewscroller
listlist
swipercarousel
buttonbutton
inputinput
textareatextarea
switchswitch
radioradio
checkboxcheckbox
imageimage
videovideo

注意: 小程序和 CML 的內(nèi)置組件傳參是不一樣的

小程序原生組件的遷移

對(duì)于原生組件,需要在多態(tài)組件中調(diào)用,并且,需要找到其他端類(lèi)似的組件。

小程序CML
xxx.web.cml可以再這里調(diào)用 Vue 第三方庫(kù)的組件
xxx.wx.cml可以在這里調(diào)用微信第三方組件庫(kù)或者微信的原生組件(origin-)
xxx.weex.cml可以在這里調(diào)用 Weex 第三方組件庫(kù)


如果希望使用小程序端的原生組件,那么可以在原生標(biāo)簽前加上 origin-,CML 框架會(huì)渲染原生組件。

如果想要用微信小程序的第三方組件庫(kù)

假設(shè),原有小程序代碼,如下:

<picker-view value="{{value}}" bindchange="bindChange">
  <picker-view-column>
    <view wx:for="{{list}}"><text>{{item}}</text></view>
  </picker-view-column>
</picker-view>

那么,使用 CML 語(yǔ)法后:

<origin-picker-view value="{{value}}" bindchange="bindChange">
  <origin-picker-view-column>
    <view c-for="{{list}}"><text>{{item}}</text></view>
  </origin-picker-view-column>
</origin-picker-view>

模板上需要替換的語(yǔ)法匯總

小程序CML
wx:ifc-if
wx:elifc-else-if
wx:elsec-else
wx:forc-for
wx:for-indexc-for-index
wx:for-itemc-for-item
wx:keyc-key
bindtapc-bind:tap
catchtapc-catch:tap

CML 對(duì)于語(yǔ)法的擴(kuò)展支持

指令的擴(kuò)展 c-show、c-model、c-show

component is 動(dòng)態(tài)組件的擴(kuò)展

事件綁定支持內(nèi)聯(lián)事件傳參數(shù)

總結(jié)

1 對(duì)于小程序的語(yǔ)法,比如wx:if wx:for等要替換成 cml 對(duì)應(yīng)的語(yǔ)法 c-if c-for

2 對(duì)于小程序的事件綁定,要轉(zhuǎn)化成 CML 的c-bind c-catch的形式,cml 擴(kuò)展了支持事件傳參

JS 內(nèi)容遷移

數(shù)據(jù)的遷移

其中需要注意點(diǎn) 小程序中的 properties 對(duì)應(yīng)于 cml 中的 props

小程序

 properties: {
    innerText: {
      type: String,
      value: 'default value',
    }
  },

CML 項(xiàng)目

props = {
  innerText: {
    type: String,
    default: 'default value',
  },
};

微信小程序 API 的遷移

假設(shè),原有小程序代碼,如下:

wx.redirectTo({
  url: 'test?id=1',
});

那么,使用 CML 語(yǔ)法后:

import cml from 'chameleon-api';
cml.redirectTo({
  path: '/pages/navigateBack/index',
  query: {
    id: 1,
  },
});

小程序的 API 文檔

這里對(duì)于 API 小程序的 API 和 CML 的 API 的文檔中對(duì)應(yīng)細(xì)則做個(gè)簡(jiǎn)單的表格,如下

微信小程序 APIchameleon-api
wx.canIUsecanIUse
系統(tǒng)信息[系統(tǒng)信息](../api/#getsysteminfo)
計(jì)時(shí)器計(jì)時(shí)器
路由路由
交互交互
設(shè)置頁(yè)面 title設(shè)置頁(yè)面 title
動(dòng)畫(huà)動(dòng)畫(huà)
網(wǎng)絡(luò)網(wǎng)絡(luò)
數(shù)據(jù)緩存數(shù)據(jù)緩存
獲取圖片信息獲取圖片信息
位置位置

以上 chameleon-api提供的接口都是支持跨多端的,對(duì)于一些沒(méi)有提供的跨多端的接口,而你的項(xiàng)目中又是必須用到的情況下,可以通過(guò)多態(tài)接口來(lái)實(shí)現(xiàn)。

小程序事件的遷移

注意,自定義組件的事件的觸發(fā)機(jī)制,映射如下:

小程序CML
this.triggerEvent(xxx,xxx)this.$cmlEmit(xxx,xxx)

事件對(duì)象參數(shù)

CML 對(duì) web native wx 各個(gè)端的事件對(duì)象進(jìn)行了統(tǒng)一代理參考。

對(duì)于灰度區(qū)組件(多態(tài)組件) 各個(gè)端的事件對(duì)象還是對(duì)應(yīng)端的事件對(duì)象,CML 框架不會(huì)對(duì)灰度區(qū) origin- 開(kāi)頭的標(biāo)簽和第三方組件標(biāo)簽上綁定的事件進(jìn)行事件代理

模塊化的遷移

小程序的模塊化

CML 的模塊化

假如 模塊文件 m1.js

module.exports = {
  info: 'I am CML',
};

xxx.cml 引用了 m1.js

import cml from 'chameleon-api'; //node_modules中的模塊
console.log('cml', cml);
const m1 = require('path/to/m1.js');
console.log('m1', m1.info); // I am CML

總結(jié)

1 小程序 JS 層用到的全局變量 wx 要通過(guò) chameleon-api 去替換成對(duì)應(yīng)的,如果沒(méi)有對(duì)應(yīng)的 API,需要通過(guò)多態(tài)接口

2 小程序中的properties data對(duì)應(yīng)于 CML 項(xiàng)目 props、data

3 小程序中的除了生命周期之外的事件都對(duì)應(yīng)在 CML 項(xiàng)目中的methods

4 CML 提供了chameleon-store,可以用來(lái)存儲(chǔ)一些全局的變量

5 小程序觸發(fā)視圖更新的setData不能再使用,chameleon 自帶了一套響應(yīng)式的數(shù)據(jù)視圖綁定

6 模塊化中引用的模塊要保證多端的適用性,參考chameleon-api

style 內(nèi)容的遷移

頁(yè)面布局的遷移

由于 CML 應(yīng)用是跨多端 Web Native 小程序框架,如果需要跨 native,必須使用 flexbox 進(jìn)行樣式布局,其他場(chǎng)景可以參考只跨 Web 和小程序的應(yīng)用

關(guān)于樣式的使用教程

模板上的樣式語(yǔ)法,基本和微信小程序是相同的;

樣式單位的遷移

如果樣式想要適配多端,需要將單位改成cpx;

假設(shè),原有小程序代碼,如下:

.demo-com {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 400rpx;
  justify-content: center;
}
.title {
  align-self: center;
  color: #61c7fc;
  font-size: 72rpx;
  margin-top: 160rpx;
  margin-bottom: 20rpx;
}
.logo {
  width: 150rpx;
  height: 150rpx;
  margin-top: 100rpx;
}

那么,使用 CML 語(yǔ)法后:

.demo-com {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 400cpx;
  justify-content: center;
}
.title {
  align-self: center;
  color: #61c7fc;
  font-size: 72cpx;
  margin-top: 160cpx;
  margin-bottom: 20cpx;
}
.logo {
  width: 150cpx;
  height: 150cpx;
  margin-top: 100cpx;
}

以上,簡(jiǎn)單的介紹了微信小程序遷移到 CML 的簡(jiǎn)單步驟,如果還有任何疑問(wèn),歡迎隨時(shí)在 CML 官方微信和官方 QQ 群里進(jìn)行反饋,我們將隨時(shí)解答你的困惑,再次感謝你對(duì) CML 的支持~

? Best wishes

? CML 團(tuán)隊(duì)


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)