微信小程序自定義組件(二)

微信小程序自定義組件

ps 由于作業(yè)部落貌似出了點問題黍檩,耽誤了點時間,找了一個stackedit.io準備寫塑煎。無奈,這是要自己建編輯器的節(jié)奏啊臭蚁。沒有一個能靠的注

為何存在組件

組件間的關系

使用relations實現組件的關系最铁,即父子關系讯赏。

定義和使用組件間的關系

有時需要使用如下的組件間的關系

 <custom-ul> 
    <custom-li> item1 </ custom-li> 
    <custom-li> item2 </ custom-li> 
</ custom-ul> 

在上方中,
兩個<custom-ul>以及<custom-li>兩個組件都為自定義組件冷尉,如果進行通信會非常的難以操作漱挎,至此通過relations完成子父組件的定義,簡化通信雀哨。
同樣的以上方的栗子作為舉例磕谅。

繼續(xù)上一個栗子,新建一個頁面雾棺,在新的頁面中使用組件間的關系膊夹。

由于同屬于一個custom大組件,所以直接在components中新建一個custom文件夾捌浩,表示一個大的新組件
由于其擁有一個子組件放刨,所以再新建一個li文件夾,表示custom-li
目錄如下

image

菜鳥一枚嘉栓,設置的不一定正確宏榕。也不一定是最正統(tǒng)的,只是感覺侵佃。╮(╯▽╰)╭

設置custom/custom.js文件的relations的值

// components/custom/custom.js
Component({
  relations: {
    './li/li' : {
      type: 'child',  // 設置關聯(lián)的目標節(jié)點為子節(jié)點
    }
  }
})

接著設置祖先節(jié)點麻昼,即設置custom/li/li.js文件的內容

// components/custom/li/li.js
Component({
  relations: {
    '../../custom': {
      type: 'parent'  // 應為祖先節(jié)點
    }
  }
})

設置組件的wxml文件

<! - 組件/自定義/立/ li.wxml  - >
< view > components / custom / li / li.wxml </ view > < slot />

<!--components/custom/custom.wxml-->
<view>components/custom/custom.wxml</view>
<slot/>

接著設置page頁面的wxml頁面

<!--pages/ming/ming.wxml-->
<text>hello world</text>
<custom-ul>
  <custom-li></custom-li>
  <custom-li></custom-li>
  <custom-li></custom-li>
  <custom-li></custom-li>
</custom-ul>

至此完成馋辈。

關聯(lián)一類組件

被微信的路徑折騰的不輕抚芦,好吧,無奈迈螟,決定重新寫

微信路徑

微信路徑太坑了叉抡。
理所應當應該是

/ 根目錄
../ 父級目錄
./ 當前目錄

結果非要

../../

至今也沒搞清楚路徑是這么回事。算了答毫,決定在同一個目錄下完成模塊的問題褥民,不在另外的分一個模塊的文件夾了。

總說

要形成的在page下的結構如下

<custom-form>
    <view>
        input
        <custom-input></custom-input>
    </view>
    <custom-submit>shubmit</custom-submit>
</custom-form>

創(chuàng)建目錄

創(chuàng)建目錄如下


image

好啦洗搂,目錄如上

這一次放棄將模塊放在另外一個文件夾消返,這一場所有的和組件相關的內容都放在同一個文件夾下 。符合組件的精神

其中form表明該為一個form的組件耘拇。module表明組件的內容撵颊,其中module下還有一個behaviors表明是behaviors的內容的模塊,input和submit表明是其子組件惫叛。

behaviors

書寫behaviors的內容倡勇。

// components/form/module/behaviors/controls

module.exports = Behavior({

// ...

})

父組件

書寫父組件及form的內容

// components/form/form.js

var formControls = require('./module/behaviors/controls.js')

Component({

relations: {

'formControls': {

type: 'descendant', // 關聯(lián)目標的節(jié)點應為子孫節(jié)點

target: formControls // 所有設置behavior的組件的節(jié)點都為其子孫節(jié)點

}

}

})

繼續(xù)書寫wxml的內容,其實就是添加一個掛載點的問題。

<!--components/form/form.wxml-->

<text>components/form/form.wxml</text>

<slot/>

input組件

// components/form/input/input.js

var formControls = require('../module/behaviors/controls.js')

Component({

behaviors: [formControls],

relations: {

'../form': {

type: 'ancestor', // 關聯(lián)的目標節(jié)點應為祖先節(jié)點

}

}

})

wxml

<!--components/form/input/input.wxml-->

<text>components/form/input/input.wxml</text>

<slot/>

submit組件

此為from的子組件

// components/form/submit/submit.js

var formControls = require('../module/behaviors/controls.js')

Component({

behaviors: [formControls],

relations: {

'../form': {

type: 'ancestor', // 關聯(lián)的目標節(jié)點應為祖先節(jié)點s

}

}

})

繼續(xù)寫wxml加上一個

<!--components/form/submit/submit.wxml-->

<text>components/form/submit/submit.wxml</text>

<label><slot/></label>

json配置文件

{

"usingComponents": {

"component": "/components/component",

"body": "/components/body/body",

"custom-form": "/components/form/form",

"custom-input": "/components/form/input/input",

"custom-submit": "/components/form/submit/submit"

}

}

編寫頁面的wxml

<custom-form>

<view>

<custom-input/>

</view>

<custom-submit/>

</custom-form>

完成(o)/
至此嘉涌,根據一個behaviors完成一個組件

抽象性節(jié)點

抽象節(jié)點類似于掛載點妻熊,但是和掛載點不同的是夸浅,可以通過屬性來更改掛載的組件。需要注意的一點是固耘,其值需要為靜態(tài)值题篷,不能為動態(tài)值,抽象節(jié)點只能使用靜態(tài)的內容厅目。

但是個人感覺和掛載點還是有一點類似的作用番枚,不過這個是通過不同的條件達到調用的目的。

抽象節(jié)點核心在于調用的時候才能確定內部需要什么組件损敷,只有調用才能確認需要的組件葫笼,核心在于將業(yè)務和邏輯分離,徹底達到消除耦合的目的拗馒。

組件的目的在于盡可能的減少業(yè)務邏輯在里面路星。
注意,組件的確是要盡可能的減少邏輯在里面诱桂,因為組件的核心在于復用洋丐,在于大量的復用。減少重復代碼的書寫挥等,即將一段業(yè)務中的重復的友绝,多次的抽象出來,提取成為一個組件肝劲,如果因為某些原因迁客,必須要存在一定的業(yè)務邏輯在里面,這個時候就需要抽象節(jié)點辞槐。

抽象節(jié)點和掛載點的不同就在上方體現出來了而姐,抽象節(jié)點是必須有的嵌灰,但是掛載點可有可無

抽象節(jié)點的核心在于分離栓辜,抽象刹悴。
再次感受抽象的重要性

在組件中使用抽象節(jié)點

在自定義模板中的一些節(jié)點,其對應的自定義組件不是由自定義組件本身確定的鹿榜,由調用者確定先朦,稱為抽象節(jié)點

這定義╮(╯▽╰)╭

例如下面的代碼

<view>
    <label>
        <selectable disabled="{{false}}"/>
    </label>
</view>

在上方的代碼中,selectable 是由調用者確定的犬缨,需要在調用的時候根據屬性值進行替換
還需要在json文件中添加如下的配置

{
    "componentGenerics": {
        "selectable": true
    }
}

直接聲明該節(jié)點為抽象節(jié)點,其值由調用者確定

使用包含抽象節(jié)點的組件

上方是在代碼中定義抽象節(jié)點棉浸。僅僅是定義怀薛,還不能使用。
如果要是使用抽象節(jié)點迷郑,需要再次添加屬性

generic 為一個選項

在page頁面中寫入如下內容

<custom-form  generic:selectable="component">

</custom-form>

表明引入一個組件枝恋,其中的抽象節(jié)點的selectable替換為component內容创倔。

需要注意的是,需要在json文件中引入component的內容

默認組件

即在未指定組件內容的時候使用的組件
在組件文件夾中的json聲明焚碌。
此時不需要使用true即可聲明抽象節(jié)點

{

"usingComponents": {},

"componentGenerics": {

"selectable": {

"default": "/components/component"

}

}

}

自定義組件擴展

自定義組件的擴展實質為提供了修改自定義組件定義段的能力畦攘。使用自定義組件的擴展能動態(tài)的修改的自定義組件的擴展。

一直別一個及其簡單的問題困擾了很久十电,es6中新增加的對象屬性聲明知押,并賦值,可以直接省去function關鍵字鹃骂。

關于es6

關于es6的問題台盯,是滴,被微信官方文檔的一個寫法糾結了很久

```js
module.exports = Behavior({
  definitionFilter(defFields) {
    defFields.data.from = 'behavior'
  },
})

就上方的寫法畏线,由于是一種新的寫法静盅,上方的等價于下方的內容

module.exports = Behavior({
    definitionFilter: function definitionfilter(defFields) {
        defFields.data.form = 'behavior'
    }
})

僅僅是一種新的es6的寫法。一種聲明私有函數的方式寝殴,一般在組件里聲明私有函數蒿叠。這個時候,可以直接省去function蚣常。
好啦市咽,最大的障礙解決了。

definitionfilter函數

Behavior() 構造器定義了一個新的段史隆,即definitionfilter段魂务。
該函數具有兩個定義段,分別是defFields 以及 definitionFilterAll 此為兩個參數
下面解釋這兩個參數

defFields參數

對于該參數來說泌射,是當前被調用使用的behavior粘姜,這個灰常簡單不在多說

definitionFilterAll 參數

這個參數為behaviors順序。
使用一個官方的栗子來解釋吧

// behavior3.js
module.exports = Behavior({
    definitionFilter(defFields, definitionFilterArr) {},
})

// behavior2.js
module.exports = Behavior({
  behaviors: [require('behavior3.js')],
  definitionFilter(defFields, definitionFilterArr) {
    // definitionFilterArr[0](defFields)
  },
})

// behavior1.js
module.exports = Behavior({
  behaviors: [require('behavior2.js')],
  definitionFilter(defFields, definitionFilterArr) {},
})

// component.js
Component({
  behaviors: [require('behavior1.js')],
})

在上方的栗子中熔酷,每個defFelds都為當前調用的behaviors孤紧,而definitionFilterArr是這樣的情況
當調用2的時候,因為會調用3的definitionFilter函數拒秘,對其內容進行更改号显,在3中的definitionFilter函數有兩個參數,第一個參數為2的behavior的定義段躺酒,即2中的各項內容進行更改押蚤,第二個參數為3的behaviors的內容,由于3沒有引用其他的behaviors羹应,所以為一個空數組

總結揽碘,當調用的時候,第一個參數為調用者的behaviors,而第二個參數為其本身的behaviors

當進行到1的時候雳刺,將會調用2的definitionFilter劫灶,其2的該函數的第一個參數為1的behaviors,和其他的一些項掖桦,第二個參數為2引用的behaviors本昏,由于2引用了3的behaviors,而3沒有引用枪汪,所以是一個只有一項的數組涌穆,該數組的內容為2引用的behaviors,即3的definitionFilter定義段

如果當調用1的時候料饥,要調用3的definitionFilter函數
分析蒲犬,3的definitionFilter函數由2的behaviors函數調用,而2的·definitionFilter函數是由1的behaviors調用岸啡,并且3的definitionFilter函數在2中的definitionFilter函數的第二個參數的第一項(數組)中有其內容原叮,所以需要在2中寫數組,用來調用3的definitionFilter函數巡蘸。
所以第2中有definitionFilterArr[0](defFields)表明是調用3的definitionFilter而參數defFields表明是2中的behaviors中的內容奋隶。

同理使用Component構造函數的時候,將會調用1的definitionFilter函數對Component內容進行更改悦荒。

最后唯欣,總結就是一句話

當調用的時候,第一個參數為調用者的behaviors搬味,而第二個參數為其本身的behaviors

官方擴展包 https://github.com/wechat-miniprogram/computed 實現動態(tài)的計算屬性

哦境氢。貌似切圖仔最重要的瀑布流還沒有學習

第三方自定義組件

終于到自己的知識范疇啦。目前已經會node.js和npm碰纬,下面的就比較好學習了萍聊。
微信小程序的官方ide支持npm
官方提供有一個模板 https://github.com/wechat-miniprogram/miniprogram-custom-component
屬于小程序的自定義腳手架的相關內容。
官方的事例的組件 https://github.com/wechat-miniprogram/slide-view
以及官方提供的命令行工具 https://github.com/wechat-miniprogram/miniprogram-cli

命令行工具

npm install -g @wechat-miniprogram/miniprogram-cli

東西有點多

安裝完成以后進行初始化

miniprogram init [options] [dirPath]

進行選擇即可悦析。

miniprogram

即第三方的自定義組件寿桨,custom-component為創(chuàng)建一個空的自定義組件目錄,miniprogram為一個小程序的自定義組件的快速的開始强戴,會有一個從github上下的一個模板亭螟,寫代碼即可。
屬于腳手架的一部分骑歹。

由于涉及到glup预烙,暫時擱置。

目錄如下

|--miniprogram_dev // 開發(fā)環(huán)境構建目錄
|--miniprogram_dist // 生產環(huán)境構建目錄
|--src // 源碼
|   |--common // 通用 js 模塊
|   |--components // 通用自定義組件
|   |--images // 圖片資源
|   |--wxml // 通用 wxml 模版資源
|   |--wxs // 通用 wxs 資源
|   |--wxss // 通用 wxss 資源
|   |
|   |--xxx.js/xxx.wxml/xxx.json/xxx.wxss // 暴露的 js 模塊/自定義組件入口文件
|
|--test // 測試用例
|--tools // 構建相關代碼
|   |--demo // demo 小程序目錄道媚,開發(fā)環(huán)境下會被拷貝生成到 miniprogram_dev 目錄中
|   |--test // 測試工具相關目錄
|   |--config.js // 構建相關配置文件
|
|--gulpfile.js

即扁掸,按照上方進行構建相關的組件即可欢嘿。目前src部分能看明白,暴露的接口和node.js的包如出一轍也糊,都是直接在主文件中進行暴露出接口的,最上方兩個文件羡宙,最開始接觸到的是git的工作流狸剃,根據git的工作流也能明白,最后test和tools這一點還有點暈狗热。測試用例使用下方的命令構建出測試用例钞馁。

npm run test

tools中的demo為一個演示,即開發(fā)者下載下來內容以后將會直接出現的內容匿刮,例如僧凰,文檔中的使用微信小程序打開這一點就是參考這樣的,
test測試工具相關目錄熟丸,進行測試的工具存放的目錄训措。例如進行自動化測試的一些腳本要書寫在這里。
config.js為進行自動化構建所要進行的文件光羞,

ps 由于構建工具未學绩鸣,構建工具的學習重點肯定是配置文件的書寫。以及對接口的暴露等纱兑。

至此呀闻,暫時結束微信小程序的自定義組件化,明天寫插件潜慎。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末捡多,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子铐炫,更是在濱河造成了極大的恐慌垒手,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驳遵,死亡現場離奇詭異淫奔,居然都是意外死亡,警方通過查閱死者的電腦和手機堤结,發(fā)現死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門唆迁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人竞穷,你說我怎么就攤上這事唐责。” “怎么了瘾带?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵鼠哥,是天一觀的道長。 經常有香客問我,道長朴恳,這世上最難降的妖魔是什么抄罕? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮于颖,結果婚禮上呆贿,老公的妹妹穿的比我還像新娘。我一直安慰自己森渐,他們只是感情好做入,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著同衣,像睡著了一般竟块。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耐齐,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天浪秘,我揣著相機與錄音,去河邊找鬼蚪缀。 笑死秫逝,一個胖子當著我的面吹牛,可吹牛的內容都是我干的询枚。 我是一名探鬼主播违帆,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼金蜀!你這毒婦竟也來了刷后?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤渊抄,失蹤者是張志新(化名)和其女友劉穎尝胆,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體护桦,經...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡含衔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了二庵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贪染。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖催享,靈堂內的尸體忽然破棺而出杭隙,到底是詐尸還是另有隱情,我是刑警寧澤因妙,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布痰憎,位于F島的核電站票髓,受9級特大地震影響,放射性物質發(fā)生泄漏铣耘。R本人自食惡果不足惜洽沟,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜗细。 院中可真熱鬧玲躯,春花似錦、人聲如沸鳄乏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽橱野。三九已至,卻和暖如春善玫,著一層夾襖步出監(jiān)牢的瞬間水援,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工茅郎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蜗元,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓系冗,卻偏偏與公主長得像奕扣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子掌敬,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內容

  • 1.創(chuàng)建一個組件 上圖中singerList是一個組件 songerList是父頁面 2.組件引用和創(chuàng)建上節(jié)已經講...
    __Nancy閱讀 10,264評論 1 3
  • 因新工作主要負責微信小程序這一塊惯豆,最近的重心就移到這一塊,該博客是對微信小程序整體的整理歸納以及標明一些細節(jié)點奔害,初...
    majun00閱讀 7,341評論 0 9
  • 一切可以妥當的一定會妥當楷兽!準備迎接奇跡!簡單想华临,認真行芯杀! 一、發(fā)掘空性 今天在網上看到一篇好文章雅潭,大意是說拒絕一些...
    belivePossible閱讀 151評論 0 0
  • 主要介紹解析XML的兩種方式 DOM4J解析:面向對象揭厚,由于是一次性讀取整個文檔到內存中,讀取大文件的時候可能會造...
    no_today閱讀 378評論 0 1
  • 眾所周知寻馏,家訪是學校與家庭共同教育好孩子的一道不可或缺的橋梁棋弥。通過家訪能及時了解學生在家學習和生活的情況以及思想動...
    趙超198165閱讀 328評論 0 0