在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美

當(dāng)前位置:雨林木風(fēng)下載站 > 應(yīng)用軟件教程 > 詳細(xì)頁(yè)面

微信小程序組件化開(kāi)發(fā)Labrador框架的介紹

微信小程序組件化開(kāi)發(fā)Labrador框架的介紹

更新時(shí)間:2025-10-08 文章作者:未知 信息來(lái)源:網(wǎng)絡(luò) 閱讀次數(shù):

導(dǎo)微信小程序,簡(jiǎn)稱小程序,英文名Mini Program,是一種不需要下載安裝即可使用的應(yīng)用,它實(shí)現(xiàn)了應(yīng)用“觸手可及”的夢(mèng)想,用戶掃一掃或搜一下即可打開(kāi)應(yīng)用。小程序是一種不用下載就能使用的應(yīng)用,也是一...
微信小程序,簡(jiǎn)稱小程序,英文名Mini Program,是一種不需要下載安裝即可使用的應(yīng)用,它實(shí)現(xiàn)了應(yīng)用“觸手可及”的夢(mèng)想,用戶掃一掃或搜一下即可打開(kāi)應(yīng)用。小程序是一種不用下載就能使用的應(yīng)用,也是一項(xiàng)門檻非常高的創(chuàng)新,經(jīng)過(guò)將近兩年的發(fā)展,已經(jīng)構(gòu)造了新的小程序開(kāi)發(fā)環(huán)境和開(kāi)發(fā)者生態(tài)。

labrador 命令

labrador init 初始化項(xiàng)目命令

注意此命令會(huì)初始化當(dāng)前的目錄為項(xiàng)目目錄。

labrador build 構(gòu)建當(dāng)前項(xiàng)目

  Usage: labrador build [options]

  Options:

    -h, --help     output usage information
    -V, --version  output the version number
    -c, --catch    在載入時(shí)自動(dòng)catch所有JS腳本的錯(cuò)誤
    -t, --test     運(yùn)行測(cè)試腳本
    -d, --debug    DEBUG模式
    -m, --minify   壓縮代碼
    -f, --force    強(qiáng)制構(gòu)建,不使用緩存

labrador watch 監(jiān)測(cè)文件變化

  Usage: labrador watch [options]

  Options:

    -h, --help     output usage information
    -V, --version  output the version number
    -c, --catch    在載入時(shí)自動(dòng)catch所有JS腳本的錯(cuò)誤
    -t, --test     運(yùn)行測(cè)試腳本
    -d, --debug    DEBUG模式

labrador 庫(kù)

labrador 庫(kù)對(duì)全局的 wx 變量進(jìn)行了封裝,將大部分 wx 對(duì)象中的方法進(jìn)行了Promise支持, 除了以 on* 開(kāi)頭或以 *Sync結(jié)尾的方法。在如下代碼中使用 labrador 庫(kù)。

import wx from 'labrador';console.log(wx.version);wx.app;         
// 和全局的 getApp() 函數(shù)效果一樣,代碼風(fēng)格不建議粗暴地訪問(wèn)全局對(duì)象和方法wx.Component;   
// Labrador 自定義組件基類wx.List;        
// Labrador 自定義組件列表類wx.PropTypes;   
// Labrador 數(shù)據(jù)類型校驗(yàn)器集合wx.login;       
// 封裝后的微信登錄接口wx.getStorage;  
// 封裝后的讀取緩存接口

我們建議不要再使用 wx.getStorageSync() 等同步阻塞方法,而在 async 函數(shù)中使用 await wx.getStorage() 異步非阻塞方法提高性能,除非遇到特殊情況。

app.js

src/app.js 示例代碼如下:

import wx from 'labrador';import {sleep} from './utils/util';export default class {
  globalData = {
    userInfo: null
  };  async onLaunch() {    //調(diào)用API從本地緩存中獲取數(shù)據(jù)
    let res = await wx.getStorage({ key: 'logs' });    let logs = res.data || [];    logs.unshift(Date.now());    await wx.setStorage({ key: 'logs', data: logs });    this.timer();
  }  async timer() {    while (true) {      console.log('hello');      await sleep(10000);
    }
  }  async getUserInfo() {    if (this.globalData.userInfo) {      return this.globalData.userInfo;
    }    await wx.login();    let res = await wx.getUserInfo();    this.globalData.userInfo = res.userInfo;    return res.userInfo;
  }
}

代碼中全部使用ES6/7標(biāo)準(zhǔn)語(yǔ)法。代碼不必聲明 use strict ,因?yàn)樵诰幾g時(shí),所有代碼都會(huì)強(qiáng)制使用嚴(yán)格模式。

代碼中并未調(diào)用全局的 App() 方法,而是使用 export 語(yǔ)法默認(rèn)導(dǎo)出了一個(gè)類,在編譯后,Labrador會(huì)自動(dòng)增加 App() 方法調(diào)用,所有請(qǐng)勿手動(dòng)調(diào)用 App() 方法。這樣做是因?yàn)榇a風(fēng)格不建議粗暴地訪問(wèn)全局對(duì)象和方法。

自定義組件

Labrador的自定義組件,是基于微信小程序框架的組件之上,進(jìn)一步自定義組合,擁有邏輯處理和樣式。

項(xiàng)目中通用自定義組件存放在 src/compontents 目錄,一個(gè)組件一般由三個(gè)文件組成,*.js 、 *.xml 和 *.less 分別對(duì)應(yīng)微信小程序框架的 js 、 wxml 和 wxss 文件。在Labardor項(xiàng)目源碼中,我們特意采用了 xml 和 less 后綴以示區(qū)別。如果組件包含單元測(cè)試,那么在組件目錄下會(huì)存在一個(gè) *.test.js 的測(cè)試腳本文件。

自定義組件示例

下面是一個(gè)簡(jiǎn)單的自定義組件代碼實(shí)例:

邏輯 src/compontents/title/title.js

import wx from 'labrador';import randomColor  from '../../utils/random-color';const { string } = wx.PropTypes;export default class Title extends wx.Component {

  propTypes = {
    text: string
  };

  props = {
    text: ''
  };

  data = {
    text: '',
    color: randomColor()
  };  onUpdate(props) {    this.setData('text', props.text);
  }  handleTap() {    this.setData({
      color: randomColor()
    });
  }
}

自定義組件的邏輯代碼和微信框架中的page很相似,最大的區(qū)別是在js邏輯代碼中,沒(méi)有調(diào)用全局的 Page() 函數(shù)聲明頁(yè)面,而是用 export 語(yǔ)法導(dǎo)出了一個(gè)默認(rèn)的類,這個(gè)類必須繼承于 labrador.Component 組件基類。

相對(duì)于微信框架中的page,Labrador自定義組件擴(kuò)展了 propTypes 、 props 、 children 選項(xiàng)及 onUpdate 生命周期函數(shù)。children 選項(xiàng)代表當(dāng)前組件中的子組件集合,此選項(xiàng)將在下文中敘述。

Labrador的目標(biāo)是構(gòu)建一個(gè)可以重用、嵌套的自定義組件方案,在現(xiàn)實(shí)情況中,當(dāng)多個(gè)組件互相嵌套組合,就一定會(huì)遇到父子組件件的數(shù)據(jù)和消息傳遞。因?yàn)樗械慕M件都實(shí)現(xiàn)了 setData 方法,所以我們可以使用this.children.foobar.setData(data) 或 this.parent.setData(data) 這樣的代碼調(diào)用來(lái)解決父子組件間的數(shù)據(jù)傳遞問(wèn)題,但是,如果項(xiàng)目中出現(xiàn)大量這樣的代碼,那么數(shù)據(jù)流將變得非常混亂。

我們借鑒了 React.js 的思想,為組件增加了 props 機(jī)制。子組件通過(guò) this.props 得到父組件給自己傳達(dá)的參數(shù)數(shù)據(jù)。父組件怎樣將數(shù)據(jù)傳遞給子組件,我們下文中敘述。

onUpdate 生命周期函數(shù)是當(dāng)組件的 props 發(fā)生變化后被調(diào)用,類似React.js中的 componentWillReceiveProps 所以我們可以在此函數(shù)體內(nèi)監(jiān)測(cè) props 的變化。

組件定義時(shí)的 propTypes 選項(xiàng)是對(duì)當(dāng)前組件的props參數(shù)數(shù)據(jù)類型的定義。 props 選項(xiàng)代表的是當(dāng)前組件默認(rèn)的各項(xiàng)參數(shù)值。propTypes 、 props 選項(xiàng)都可以省略,但是強(qiáng)烈建議定義 propTypes,因?yàn)檫@樣可以使得代碼更清晰易懂,另外還可以通過(guò)Labrador自動(dòng)檢測(cè)props值類型,以減少BUG。為優(yōu)化性能,只有在DEBUG模式下才會(huì)自動(dòng)檢測(cè)props值類型。

編譯時(shí)加上 -d 參數(shù)時(shí)即可進(jìn)入DEBUG模式,在代碼中任何地方都可以使用魔術(shù)變量 __DEBUG__ 來(lái)判斷是否是DEBUG模式。

另外,Labrador自定義組件的 setData 方法,支持兩種傳參方式,第一種像微信框架一樣接受一個(gè) object 類型的對(duì)象參數(shù),第二種方式接受作為KV對(duì)的兩個(gè)參數(shù),setData 方法將自動(dòng)將其轉(zhuǎn)為 object。

布局 src/compontents/title/title.xml

<view class="text-view">
  <text class="title-text" catchtap="handleTap" style="color:{{color}};">{{text}}</text>
</view>

XML布局文件和微信WXML文件語(yǔ)法完全一致,只是擴(kuò)充了兩個(gè)自定義標(biāo)簽 <component/> 和 <list/>,下文中詳細(xì)敘述。

樣式 src/compontents/title/title.less

.title-text {  font-weight: bold;  font-size: 2em;
}

雖然我們采用了LESS文件,但是由于微信小程序框架的限制,不能使用LESS的層級(jí)選擇及嵌套語(yǔ)法。但是我們可以使用LESS的變量、mixin、函數(shù)等功能方便開(kāi)發(fā)。

頁(yè)面

我們要求所有的頁(yè)面必須存放在 pages 目錄中,每個(gè)頁(yè)面的子目錄中的文件格式和自定義組件一致,只是可以多出一個(gè)*.json 配置文件。

頁(yè)面示例

下面是默認(rèn)首頁(yè)的示例代碼:

邏輯 src/pages/index/index.js

import wx from 'labrador';import List from '../../components/list/list';import Title from '../../components/title/title';import Counter from '../../components/counter/counter';export default class Index extends wx.Component {
  data = {
    userInfo: {},
    mottoTitle: 'Hello World',
    count: 0
  };

  children = {
    list: new List(),
    motto: new Title({ text: '@mottoTitle', hello: '@mottoTitle' }),
    counter: new Counter({ count: '@count', onChange: '#handleCountChange' })
  };  handleCountChange(count) {    this.setData({ count });
  }  //事件處理函數(shù)
  handleViewTap() {    wx.navigateTo({
      url: '../logs/logs'
    });
  }  async onLoad() {    try {      //調(diào)用應(yīng)用實(shí)例的方法獲取全局?jǐn)?shù)據(jù)
      let userInfo = await wx.app.getUserInfo();      //更新數(shù)據(jù)
      this.setData({ userInfo });      this.update();
    } catch (error) {      console.error(error.stack);
    }
  }  onReady() {    this.setData('mottoTitle', 'Labrador');
  }
}

頁(yè)面代碼的格式和自定義組件的格式一模一樣,我們的思想是 頁(yè)面也是組件。

js邏輯代碼中同樣使用 export default 語(yǔ)句導(dǎo)出了一個(gè)默認(rèn)類,也不能手動(dòng)調(diào)用 Page() 方法,因?yàn)樵诰幾g后,pages 目錄下的所有js文件全部會(huì)自動(dòng)調(diào)用 Page() 方法聲明頁(yè)面。

我們看到組件類中,有一個(gè)對(duì)象屬性 children ,這個(gè)屬性定義了該組件依賴、包含的其他自定義組件,在上面的代碼中頁(yè)面包含了三個(gè)自定義組件 list 、 title 和 counter ,這個(gè)三個(gè)自定義組件的 key 分別為 list 、 motto 和 counter。

自定義組件類在實(shí)例化時(shí)接受一個(gè)類型為 object 的參數(shù),這個(gè)參數(shù)就是父組件要傳給子組件的props數(shù)據(jù)。一般情況下,父組件傳遞給子組件的props屬性在其生命周期中是不變的,這是因?yàn)镴S的語(yǔ)法和小程序框架的限制,沒(méi)有React.js的JSX靈活。但是我們可以傳遞一個(gè)以 @ 開(kāi)頭的屬性值,這樣我們就可以把子組建的 props 屬性值綁定到父組件的 data 上來(lái),當(dāng)父組件的data 發(fā)生變化后,Labrador將自動(dòng)更新子組件的 props。例如上邊代碼中,將子組件 motto 的 text 屬性綁定到了@mottoTitle。那么在 onReady 方法中,將父組件的 mottoTitle 設(shè)置為 Labrador,那么子組件 motto 的 text 屬性就會(huì)自動(dòng)變?yōu)?Labrador。如果屬性值以 # 開(kāi)頭,則將父組件的屬性(非data的屬性)直接綁定到子組件 props,如上邊代碼中的 #handleCountChange,會(huì)將父組件的 handleCountChange 方法綁定到子組件的 props.onChange 屬性,這樣子組件中可以通過(guò)調(diào)用 this.props.onChange(newValue) 來(lái)通知父組件數(shù)據(jù)變化。

頁(yè)面也是組件,所有的組件都擁有一樣的生命周期函數(shù)onLoad, onReady, onShow, onHide, onUnload,onUpdate 以及setData函數(shù)。

componets 和 pages 兩個(gè)目錄的區(qū)別在于,componets 中存放的組件能夠被智能加載,pages 目錄中的組件在編譯時(shí)自動(dòng)加上 Page() 調(diào)用,所以,pages 目錄中的組件不能被其他組件調(diào)用,否則將出現(xiàn)多次調(diào)用Page()的錯(cuò)誤。如果某個(gè)組件需要重用,請(qǐng)存放在 componets 目錄或打包成NPM包。

布局 src/pages/index/index.xml

<view class="container">
  <view class="userinfo" catchtap="handleViewTap">
    <image class="userinfo-avatar" src="{{ userInfo.avatarUrl }}" background-size="cover"/>
    <text class="userinfo-nickname">{{ userInfo.nickName }}</text>
  </view>
  <view class="usermotto">
    <component key="motto" name="title"/>
  </view>
  <component key="list"/>
  <component key="counter"/>
</view>

XML布局代碼中,使用了Labrador提供的 <component/> 標(biāo)簽,此標(biāo)簽的作用是導(dǎo)入一個(gè)自定義子組件的布局文件,標(biāo)簽有兩個(gè)屬性,分別為 key (必選)和 name (可選,默認(rèn)為key的值)。key 與js邏輯代碼中的組件 key 對(duì)應(yīng),name 是組件的目錄名。key 用來(lái)綁定組件JS邏輯對(duì)象的 children 中對(duì)應(yīng)的數(shù)據(jù), name 用于在src/componets 和 node_modules 目錄中尋找子組件模板。

樣式 src/pages/index/index.less

@import 'list';@import 'title';@import 'counter';.motto-title-text {  font-size: 3em;  padding-bottom: 1rem;
}/* ... */

LESS樣式文件中,我們使用了 @import 語(yǔ)句加載所有子組件樣式,這里的 @import 'list' 語(yǔ)句按照LESS的語(yǔ)法,會(huì)首先尋找當(dāng)前目錄 src/pages/index/ 中的 list.less 文件,如果找不到就會(huì)按照Labrador的規(guī)則智能地嘗試尋找 src/componets和 node_modules 目錄中的組件樣式。

接下來(lái),我們定義了 .motto-title-text 樣式,這樣做是因?yàn)?motto key 代表的title組件的模板中(src/compontents/title/title.xml)有一個(gè)view 屬于 title-text 類,編譯時(shí),Labrador將自動(dòng)為其增加一個(gè)前綴motto- ,所以編譯后這個(gè)view所屬的類為 title-text motto-title-text (可以查看 dist/pages/index/index.xml)。那么我們就可以在父組件的樣式代碼中使用 .motto-title-text 來(lái)重新定義子組件的樣式。

Labrador支持多層組件嵌套,在上述的實(shí)例中,index 包含子組件 list 和 title,list 包含子組件 title,所以在最終顯示時(shí),index 頁(yè)面上回顯示兩個(gè) title 組件。

詳細(xì)代碼請(qǐng)參閱 labrador init 命令生成的示例項(xiàng)目。

自定義組件列表

Labrador 0.5版本后支持循環(huán)調(diào)用自定義組件生成一個(gè)列表。

邏輯 src/components/list/list.js

import wx from 'labrador';import Title from '../title/title';import Item from '../item/item';import { sleep } from '../../utils/util';export default class List extends wx.Component {

  data = {
    items: [
      { title: 'Labrador' },
      { title: 'Alaska' }
    ]
  };

  children = {
    title: new Title({ text: 'The List Title' }),
    listItems: new wx.List(Item, 'items', {
      item: '>>',
      title: '>title',
      isNew: '>isNew',
      onChange: '#handleChange'
    })
  };  async onLoad() {    await sleep(1000);    this.setData({
      items: [{ title: 'Collie', isNew: true }].concat(this.data.items)
    });
  }  handleChange(component, title) {    let item = this.data.items[component.key];    item.title = title;    this.setData('items', this.data.items);
  }
}

在上邊代碼中的 children.listItems 子組件定義時(shí),并沒(méi)有直接實(shí)例化子組件類,而是實(shí)例化了一個(gè) labrador.List 類,這個(gè)類是Labrador中專門用來(lái)管理組件列表。labrador.List 實(shí)例化時(shí),接受三個(gè)參數(shù):

第一個(gè)參數(shù)是列表中的自定義組件類,請(qǐng)將原始類傳入即可,不用實(shí)例化。

第二個(gè)參數(shù)是父組件上 data 屬性指向,指向的屬性必須是一個(gè)數(shù)組,例如上述代碼中,第二個(gè)參數(shù)為 items ,則當(dāng)前父組件的 data.items 屬性是一個(gè)數(shù)組,這個(gè)數(shù)組又多少個(gè)元素,那么子組件列表中就自動(dòng)產(chǎn)生多少個(gè)子組件。子組件的數(shù)量跟隨data.items 數(shù)組動(dòng)態(tài)變化,Labrador會(huì)自動(dòng)實(shí)例化或銷毀相應(yīng)的子組件。銷毀子組件時(shí),子組件的 onUnload() 方法將會(huì)被調(diào)用。

第三個(gè)參數(shù)是子組件 props 數(shù)據(jù)綁定設(shè)置,如果屬性值以 > 開(kāi)頭,則將 data.items 中對(duì)應(yīng)元素的屬性綁定到子組件的props。如果屬性值以 # 開(kāi)頭,則將父組件的方法綁定到子組件的 props 中。注意,因?yàn)樽咏M件是一個(gè)列表,所以為了區(qū)別,父組件對(duì)應(yīng)的方法被調(diào)用時(shí),第一個(gè)參數(shù)為子組件的實(shí)例,第二個(gè)及其之后的參數(shù)才是子組件中傳回的參數(shù)。如果屬性值是 >> 則將整個(gè)列表項(xiàng)數(shù)據(jù)綁定到對(duì)應(yīng)的 props 上。

模板 src/components/list/list.xml

<view class="list">
  <component key="title" name="title"/>
  <list key="listItems" name="item"/>
</view>

在XML模板中,調(diào)用 <list/> 標(biāo)簽即可自動(dòng)渲染子組件列表。和 <component/> 標(biāo)簽類似,<list/> 同樣也有兩個(gè)屬性,key 和 name。Labrador編譯后,會(huì)自動(dòng)將 <list/> 標(biāo)簽編譯成 wx:for 循環(huán)。

自動(dòng)化測(cè)試

我們規(guī)定項(xiàng)目中所有后綴為 *.test.js 的文件為測(cè)試腳本文件。每一個(gè)測(cè)試腳本文件對(duì)應(yīng)一個(gè)待測(cè)試的JS模塊文件。例如src/utils/util.js 和 src/utils/utils.test.js 。這樣,項(xiàng)目中所有模塊和其測(cè)試文件就全部存放在一起,方便查找和模塊劃分。這樣規(guī)劃主要是受到了GO語(yǔ)言的啟發(fā),也符合微信小程序一貫的目錄結(jié)構(gòu)風(fēng)格。

在編譯時(shí),加上 -t 參數(shù)即可自動(dòng)調(diào)用測(cè)試腳本完成項(xiàng)目測(cè)試,如果不加 -t 參數(shù),則所有測(cè)試腳本不會(huì)被編譯到 dist 目錄,所以不必?fù)?dān)心項(xiàng)目會(huì)肥胖。

普通JS模塊測(cè)試

測(cè)試腳本中使用 export 語(yǔ)句導(dǎo)出多個(gè)名稱以 test* 開(kāi)頭的函數(shù),這些函數(shù)在運(yùn)行后會(huì)被逐個(gè)調(diào)用完成測(cè)試。如果test測(cè)試函數(shù)在運(yùn)行時(shí)拋出異常,則視為測(cè)試失敗,例如代碼:

// src/util.js// 普通項(xiàng)目模塊文件中的代碼片段,導(dǎo)出了一個(gè)通用的add函數(shù)export function add(a, b) {  return a + b;
}
// src/util.test.js// 測(cè)試腳本文件代碼片段import assert from 'assert';//測(cè)試 util.add() 函數(shù)export function testAdd(exports) {  assert(exports.add(1, 1) === 2);
}

代碼中 testAdd 即為一個(gè)test測(cè)試函數(shù),專門用來(lái)測(cè)試 add() 函數(shù),在test函數(shù)執(zhí)行時(shí),會(huì)將目標(biāo)模塊作為參數(shù)傳進(jìn)來(lái),即會(huì)將 util.js 中的 exports 傳進(jìn)來(lái)。

自定義組件測(cè)試

自定義組件的測(cè)試腳本中可以導(dǎo)出兩類測(cè)試函數(shù)。第三類和普通測(cè)試腳本一樣,也為 test* 函數(shù),但是參數(shù)不是 exports 而是運(yùn)行中的、實(shí)例化后的組件對(duì)象。那么我們就可以在test函數(shù)中調(diào)用組件的方法或則訪問(wèn)組件的props 和 data 屬性,來(lái)測(cè)試行為。另外,普通模塊測(cè)試腳本是啟動(dòng)后就開(kāi)始逐個(gè)運(yùn)行 test* 函數(shù),而組件測(cè)試腳本是當(dāng)組件 onReady 以后才會(huì)開(kāi)始測(cè)試。

自定義組件的第二類測(cè)試函數(shù)是以 on* 開(kāi)頭,和組件的生命周期函數(shù)名稱一模一樣,這一類測(cè)試函數(shù)不是等到組件 onReady以后開(kāi)始運(yùn)行,而是當(dāng)組件生命周期函數(shù)運(yùn)行時(shí)被觸發(fā)。函數(shù)接收兩個(gè)參數(shù),第一個(gè)為組件的對(duì)象引用,第二個(gè)為run 函數(shù)。比如某個(gè)組件有一個(gè) onLoad 測(cè)試函數(shù),那么當(dāng)組件將要運(yùn)行 onLoad 生命周期函數(shù)時(shí),先觸發(fā) onLoad 測(cè)試函數(shù),在測(cè)試函數(shù)內(nèi)部調(diào)用 run() 函數(shù),繼續(xù)執(zhí)行組件的生命周期函數(shù),run() 函數(shù)返回的數(shù)據(jù)就是生命周期函數(shù)返回的數(shù)據(jù),如果返回的是Promise,則代表生命周期函數(shù)是一個(gè)異步函數(shù),測(cè)試函數(shù)也可以寫為async 異步函數(shù),等待生命周期函數(shù)結(jié)束。這樣我們就可以獲取run()前后兩個(gè)狀態(tài)數(shù)據(jù),最后對(duì)比,來(lái)測(cè)試生命周期函數(shù)的運(yùn)行是否正確。

第三類測(cè)試函數(shù)與生命周期測(cè)試函數(shù)類似,是以 handle* 開(kāi)頭,用以測(cè)試事件處理函數(shù)是否正確,是在對(duì)應(yīng)事件發(fā)生時(shí)運(yùn)行測(cè)試。例如:

// src/components/counter/counter.test.jsexport function handleTap(c, run) {  let num = c.data.num;  run();  let step = c.data.num - num;  if (step !== 1) {    throw new Error('計(jì)數(shù)器點(diǎn)擊一次應(yīng)該自增1,但是自增了' + step);
  }
}

生命周期測(cè)試函數(shù)和事件測(cè)試函數(shù)只會(huì)執(zhí)行一次,自動(dòng)化測(cè)試的結(jié)果將會(huì)輸出到Console控制臺(tái)。

項(xiàng)目配置文件

labrador init 命令在初始化項(xiàng)目時(shí),會(huì)在項(xiàng)目根目錄中創(chuàng)建一個(gè) .labrador 項(xiàng)目配置文件,如果你的項(xiàng)目是使用 labrador-cli 0.3 版本創(chuàng)建的,可以手動(dòng)增加此文件。

配置文件為JSON格式,默認(rèn)配置為:

{  "npmMap":{
  },  "uglify":{    "mangle": [],    "compress": {      "warnings": false
    }
  },  "classNames": {    "for-test":true
  }
}

npmMap 屬性為NPM包映射設(shè)置,例如 {"underscore":"lodash"} 配置,如果你的源碼中有require('underscore') 那么編譯后將成為 require('lodash')。這樣做是為了解決小程序的環(huán)境限制導(dǎo)致一些NPM包無(wú)法使用的問(wèn)題。比如我們的代碼必須依賴于包A,A又依賴于B,如果B和小程序不兼容,將導(dǎo)致A也無(wú)法使用。在這總情況下,我們可以Fork一份B,起名為C,將C中與小程序不兼容的代碼調(diào)整下,最后在項(xiàng)目配置文件中將B映射為C,那么在編譯后就會(huì)繞過(guò)B而加載C,從而解決這個(gè)問(wèn)題。

uglify 屬性為 UglifyJs2 的壓縮配置,在編譯時(shí)附加 -m 參數(shù)即可對(duì)項(xiàng)目中的所有文件進(jìn)行壓縮處理。

classNames 屬性指定了不壓縮的WXSS類名,在壓縮模式下,默認(rèn)會(huì)將所有WXSS類名壓縮為非常短的字符串,并拋棄所有WXML頁(yè)面中未曾使用的樣式類,如果指定了該配置項(xiàng),則指定的類不會(huì)被壓縮和拋棄。這個(gè)配置在動(dòng)態(tài)類名的情況下非常實(shí)用,比如XML中class="text-{{color}}",在編譯LESS時(shí),無(wú)法確定LESS中的.text-red類是否被用到,所以需要配置此項(xiàng)強(qiáng)制保留text-red類。

ChangeLog

2016-10-09

labrador 0.3.0

重構(gòu)自定義組件支持綁定子組件數(shù)據(jù)和事件

2016-10-12

labrador 0.4.0

增加自定義組件props機(jī)制

自動(dòng)化測(cè)試

UglifyJS壓縮集成

NPM包映射

增加.labrador項(xiàng)目配置文件

2016-10-13

labrador 0.4.2

修復(fù)組件setData方法優(yōu)化性能產(chǎn)生的數(shù)據(jù)不同步問(wèn)題

在DEBUG模式下輸出調(diào)試信息

2016-10-16

labrador 0.5.0

新增組件列表

重構(gòu)XML模板編譯器

編譯時(shí)綁定事件改為事件發(fā)生時(shí)自動(dòng)分派

以上就是微信小程序組件化開(kāi)發(fā)Labrador框架的介紹的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!


小程序是一種不需要下載安裝即可使用的應(yīng)用,它實(shí)現(xiàn)了應(yīng)用“觸手可及”的夢(mèng)想,用戶掃一掃或者搜一下即可打開(kāi)應(yīng)用。

溫馨提示:喜歡本站的話,請(qǐng)收藏一下本站!

本類教程下載

系統(tǒng)下載排行

在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美
  • <li id="86scu"><menu id="86scu"></menu></li>
    <li id="86scu"></li>
    <button id="86scu"></button>
  • <s id="86scu"></s><button id="86scu"><menu id="86scu"></menu></button>
  • 美女扒开大腿让男人桶| 免费久久久久久| 欧美交换配乱吟粗大25p| 男人插女人下面免费视频| 台湾无码一区二区| 欧美xxxx吸乳| 红桃一区二区三区| 午夜视频在线观| 一级黄色录像在线观看| 手机在线看福利| 色一情一区二区| 在线观看视频在线观看| 亚洲五月激情网| 国产乱叫456| 91日韩精品视频| 香蕉视频xxxx| 菠萝蜜视频在线观看入口| 男女视频在线观看网站| 亚洲av首页在线| 国产精品一区二区免费在线观看| 大陆av在线播放| 熟妇人妻va精品中文字幕| 视频二区在线播放| 国产盗摄视频在线观看| av免费看网址| 激情五月亚洲色图| 精品一区二区成人免费视频 | 91欧美一区二区三区| 在线观看免费黄色片| 免费一级特黄特色毛片久久看| 成人中文字幕在线播放| 我看黄色一级片| 毛片av在线播放| 在线观看免费成人av| 777久久精品一区二区三区无码| 免费无码毛片一区二三区| 天天爽天天爽夜夜爽| 日本黄色播放器| 日本成年人网址| 强开小嫩苞一区二区三区网站 | 国产无套粉嫩白浆内谢的出处| 欧美wwwwwww| 精品久久久久久无码中文野结衣| 超碰在线97免费| 97视频在线免费| 亚洲天堂第一区| 不卡的在线视频| 日韩欧美一区二| 女人色极品影院| 国产性生活一级片| 天天影视综合色| 成人毛片视频网站| 日韩 欧美 自拍| 不卡的在线视频| 91看片在线免费观看| 国内外成人激情视频| 97超碰在线人人| 国产一二三四区在线观看| 欧美wwwwwww| 日韩一区二区三区久久| 99精品视频播放| 熟女人妇 成熟妇女系列视频| 日韩欧美不卡在线| 欧美一区二区激情| 无颜之月在线看| 国产av熟女一区二区三区| 国产精品亚洲天堂| 欧美日韩视频免费在线观看| 久久黄色片网站| 天天干天天爽天天射| 国产精品视频黄色| 国产又大又黄又猛| av亚洲天堂网| 亚洲高清在线不卡| 国产探花在线观看视频| 国产精品一区在线免费观看| 青娱乐精品在线| 国产 国语对白 露脸| 男人j进女人j| 成人毛片一区二区| 免费激情视频在线观看| 天天综合网久久| 亚洲av综合色区| 两根大肉大捧一进一出好爽视频| 国产69精品久久久久久久| 欧美黄色免费影院| 中文字幕第38页| 丰满人妻一区二区三区53号| 国产精品视频网站在线观看| 1024精品视频| 中文字幕线观看| 亚洲色欲久久久综合网东京热| 777777av| 手机av在线网| 欧美成人高潮一二区在线看| 无码人妻丰满熟妇区毛片| av免费在线播放网站| 中文字幕黄色大片| 啊啊啊一区二区| 日本一级淫片演员| 国产视频一区二区视频| a级片一区二区| 日本中文字幕高清| 大伊香蕉精品视频在线| 亚洲视频在线a| 亚洲 欧美 综合 另类 中字| 亚洲激情在线观看视频| 国产精品久久..4399| 中文久久久久久| 日本a视频在线观看| 香蕉视频在线网址| 国产裸体免费无遮挡| 丁香六月激情婷婷| 91插插插影院| 999在线观看| 欧美精品成人网| 青青青青草视频| 日韩av影视大全| 制服丝袜综合网| 女人另类性混交zo| 欧美成人三级在线视频| 2021国产视频| а 天堂 在线| 午夜免费福利视频在线观看| 国产欧美高清在线| 久久国产乱子伦免费精品| 又大又硬又爽免费视频| 久久天天东北熟女毛茸茸| 天堂视频免费看| 日日干日日操日日射| 高清一区在线观看| 污网站免费在线| 亚洲77777| 99sesese| 亚洲视频在线不卡| 色黄视频免费看| 2021狠狠干| a级片一区二区| 日本午夜激情视频| 欧美牲交a欧美牲交| 鲁一鲁一鲁一鲁一澡| www.爱色av.com| 91在线视频观看免费| 亚洲精品一二三四五区| 91看片破解版| 六月婷婷激情网| 成年人午夜视频在线观看| 国产三区在线视频| 怡红院亚洲色图| 中文字幕一区二区三区四区五区人 | 日本一本中文字幕| 99精品在线免费视频| 国产免费视频传媒| 天天干天天色天天干| 欧美黑人在线观看| 男人的天堂99| 一级淫片在线观看| 国产精品裸体瑜伽视频| 成年人在线观看视频免费| 四虎影院一区二区| 妺妺窝人体色www在线小说| 香港日本韩国三级网站| 精品日韩在线播放| 色婷婷综合久久久久中文字幕| 亚洲国产日韩欧美在线观看| 视色,视色影院,视色影库,视色网 日韩精品福利片午夜免费观看 | 可以免费观看av毛片| 亚欧精品在线视频| 国产亚洲天堂网| av动漫免费观看| 老头吃奶性行交视频| 欧美日韩一级在线| 成人一区二区三| www.av91| 亚洲一级片av| 国产一级特黄a大片免费| 国产激情在线看| 中文字幕成人免费视频| 久久久久久免费看| 欧美一级特黄aaaaaa在线看片| 99999精品视频| 国产91porn| 欧美xxxxxbbbbb| 午夜在线观看av| 成人在线观看黄| www.99热这里只有精品| 免费看av软件| 五月天婷婷影视| 777一区二区| 天天干天天干天天干天天干天天干| 国产尤物av一区二区三区| 日本不卡一区二区在线观看| www.日日操| 亚洲成色www.777999| 国产肥臀一区二区福利视频| 中国丰满熟妇xxxx性| 久久人妻无码一区二区| 肉大捧一出免费观看网站在线播放| www.51色.com| 国产成人精品免费看在线播放|