微信小程序中的behaviors
概括
一句話總結(jié): behaviors是用于組件間代碼共享的特性, 類似一些編程語言中的'mixin'或者'traits'.
A.每個(gè)behaviors包含一組屬性、數(shù)據(jù)、生命周期函數(shù)、自定義方法 -> 組件引用它時(shí), 屬性、數(shù)據(jù)、生命周期函數(shù)、自定義方法都會(huì)被合并到組件中,生命周期函數(shù)也會(huì)在對(duì)應(yīng)的時(shí)機(jī)被調(diào)用.
B. 每個(gè)組件可以引用多個(gè)behavior, behavior也可引用其它behavior;
Demo演示
下文主要貼出了主要代碼, 可自行拷貝運(yùn)行.
頁面級(jí)wxml
// 新建page, 頁面級(jí)wxml <test-comp></test-comp> // 頁面級(jí)json { "usingComponents": { "test-comp": "../components/testComp/testComp" } }
組件級(jí)wxml
// 新建個(gè)組件, 組件級(jí)wxml <view>屬性: {{myBehaviorProperty}} --- {{myCompProperty}}</view> <view>數(shù)據(jù): {{myBehaviorData}} --- {{myCompData}}</view> <view bind:tap="myBehaviorMethod">觸發(fā)behavior的自定義方法</view> <view bind:tap="myCompMethod">觸發(fā)組件的自定義方法</view> // 組件級(jí)js import testBehavior from './testBehavior' Component({ behaviors: [testBehavior], properties: { myCompProperty: { type: String, value: '' } }, data: { myCompData: 'myCompData' }, created: function (){ console.log('[my-component]- created') }, attached: function (){ console.log('[my-component]- attached') }, ready: function (){ console.log('[my-component]- ready') }, methods: { myCompMethod: function () { console.log('[my-component]- method') } } })
behavior級(jí)
// behavior級(jí) export default Behavior({ behaviors: [], properties: { myBehaviorProperty: { type: String, value: 'myBehaviorProperty' } }, data: { myBehaviorData: 'myBehaviorData' }, created: function () { console.log('[my-behavior]- created') }, attached: function () { console.log('[my-behavior]- attached') }, ready: function () { console.log('[my-behavior]- ready') }, methods: { myBehaviorMethod: function () { console.log('[my-behavior]- method') } } })
先來對(duì)上述代碼做一波解析:
behavior結(jié)構(gòu):
屬性: myBehaviorProperty
數(shù)據(jù): myBehaviorData
生命周期: created() && attached() && ready()
自定義方法: myBehaviorMethod
組件引入該behaviors后的結(jié)構(gòu):
屬性: myBehaviorProperty、 myCompProperty
數(shù)據(jù): myBehaviorData、myCompData
生命周期: created() && attached() && ready()
自定義方法: myBehaviorMethod、myCompMethod
緊接著, 來看看代碼運(yùn)行結(jié)果: 也許你會(huì)對(duì)輸出有疑問, 先不著急, 慢慢往下看.
進(jìn)階演示
上面的Demo僅演示了最基礎(chǔ)的behaviors的用法, 接下來我們看看遇到同名的屬性or數(shù)據(jù)or生命周期方法or自定義方法, 該屬性會(huì)做些什么呢?
1. 若具有同名的屬性或方法
A. 若組件本身有, 則組件會(huì)覆蓋behavior;
B. 若存在嵌套子behaviors的情況, 則父behavior會(huì)覆蓋子behavior;
Demo演示: 基于上面的Demo代碼, 追加如下部分
// 新建個(gè)組件, 組件級(jí)wxml <view bind:tap="sameMethod">同名屬性: {{sameProperty}}</view> // 組件級(jí)js properties: { sameProperty: { type: String, value: 'sameProperty-myCompProperty' } }, methods: { sameMethod: function (){ console.log('[my-component]- sameMethod') } } // behavior級(jí) properties: { sameProperty: { type: String, value: 'sameProperty-myBehaviorProperty' } }, methods: { sameMethod: function (){ console.log('[my-behavior]- sameMethod') } }
上述代碼表現(xiàn)形式如下: 組件的同名屬性覆蓋了behavior的同名屬性; 點(diǎn)擊自定義方法, 觸發(fā)的是組件的自定義方法.
至此, 你會(huì)不會(huì)好奇如果屬性是個(gè)object, 是怎么個(gè)表現(xiàn)形式呢, 接下來看看實(shí)際效果.
// 新建個(gè)組件, 組件級(jí)wxml <view>同名屬性: {{sameProperty && sameProperty.val1}}</view> <view>同名屬性: {{sameProperty && sameProperty.val2}}</view> // 組件級(jí)js properties: { sameProperty: { type: Object, value: { val1: '[my-component]-同名屬性類型是對(duì)象' } } } // behavior級(jí) properties: { sameProperty: { type: Object, value: { val1: '[my-behavior]-同名屬性類型是對(duì)象', val2: '[my-behavior]-體現(xiàn)同名對(duì)象類型不會(huì)做合并' } } }
上述代碼表現(xiàn)形式如下: 同名屬性即使是對(duì)象類型, 也只會(huì)做覆蓋,
區(qū)別于下文的同名數(shù)據(jù)的合并操作哦.
2. 若有同名的數(shù)據(jù)
A. 若數(shù)據(jù)類型是對(duì)象, 進(jìn)行對(duì)象合并;
B. 其它類型會(huì)進(jìn)行數(shù)據(jù)覆蓋, 覆蓋原則:組件 > 父behavior > 子behavior; 靠后的behavior > 靠前的behavior;
Demo演示: 針對(duì)數(shù)據(jù)是對(duì)象&非對(duì)象
// 組件級(jí)js data: { sameObj: { val1: '[my-component]-同名數(shù)據(jù)類型是對(duì)象' }, sameData: false }, ready: function (){ console.log('[my-component]- ready') console.log('[my-behavior]- 同名數(shù)據(jù)', this.data.sameObj, this.data.sameData) }, // behavior級(jí) data: { sameObj: { val1: '[my-behavior]-同名數(shù)據(jù)類型是對(duì)象', val2: '[my-behavior]-體現(xiàn)同名數(shù)據(jù)類型做合并' }, sameData: true },
上述代碼表現(xiàn)形式如下: 同名數(shù)據(jù)對(duì)象做合并, 同名數(shù)據(jù)非對(duì)象做覆蓋.
3. 若有同名的生命周期函數(shù)
不會(huì)被覆蓋、而是在對(duì)應(yīng)的觸發(fā)時(shí)機(jī)內(nèi)逐個(gè)調(diào)用:
A. 不同的生命周期之間, 遵循組件生命周期的執(zhí)行順序;
B. 同種生命周期函數(shù):
①. behavior優(yōu)先于組件執(zhí)行;
②. 子behavior優(yōu)先于父behavior執(zhí)行;
③. 靠前的behavior優(yōu)先于靠后的behavior執(zhí)行;
C. 如果同一個(gè) behavior 被一個(gè)組件多次引用,它定義的生命周期函數(shù)只會(huì)被執(zhí)行一次;
應(yīng)用場(chǎng)景
相信到了這里, 你應(yīng)該明白了Demo演示中控制臺(tái)的輸出是基于什么來輸出的, 接下來我們看看什么樣的應(yīng)用場(chǎng)景會(huì)考慮使用該屬性呢?
如下圖, 有個(gè)中間彈窗組件&&底部彈窗組件, 均內(nèi)聚有如下功能點(diǎn):
A. 觸發(fā)某一條件后, 出現(xiàn)該彈窗;
B. 點(diǎn)擊遮罩層, 關(guān)閉彈窗;
考慮下如果將彈窗顯示跟隱藏的邏輯放在behaviors里面, 是否能避免同份代碼邏輯寫2遍的問題呢.
Page中不能使用behaviors、只能在Components中使用!!!!!! 故若遇到真想使用behaviors屬性的頁面, 試試把某塊頁面內(nèi)容抽離成組件, 然后引用組件的方式去實(shí)現(xiàn).
最后
behaviors
是用于組件間代碼共享的特性,類似于一些編程語言中的 “mixins” 或 “traits”。
每個(gè) behavior
可以包含一組屬性、數(shù)據(jù)、生命周期函數(shù)和方法。組件引用它時(shí),它的屬性、數(shù)據(jù)和方法會(huì)被合并到組件中,生命周期函數(shù)也會(huì)在對(duì)應(yīng)時(shí)機(jī)被調(diào)用。 每個(gè)組件可以引用多個(gè) behavior
,behavior
也可以引用其它 behavior
。
屬性&方法
注冊(cè)一個(gè) behavior
,接受一個(gè) Object
類型的參數(shù)。
定義段 | 類型 | 是否必填 | 描述 | 最低版本 |
---|---|---|---|---|
properties | Object Map | 否 | 組件的對(duì)外屬性,是屬性名到屬性設(shè)置的映射表 | |
data | Object | 否 | 組件的內(nèi)部數(shù)據(jù),和 properties 一同用于組件的模板渲染 | |
observers | Object | 否 | 組件數(shù)據(jù)字段監(jiān)聽器,用于監(jiān)聽 properties 和 data 的變化,參見 數(shù)據(jù)監(jiān)聽器 | 2.6.1 |
methods | Object | 否 | 組件的方法,包括事件響應(yīng)函數(shù)和任意的自定義方法,關(guān)于事件響應(yīng)函數(shù)的使用,參見 組件間通信與事件 | |
behaviors | String Array | 否 | 類似于mixins和traits的組件間代碼復(fù)用機(jī)制,參見 behaviors | |
created | Function | 否 | 組件生命周期函數(shù)-在組件實(shí)例剛剛被創(chuàng)建時(shí)執(zhí)行,注意此時(shí)不能調(diào)用 setData ) | |
attached | Function | 否 | 組件生命周期函數(shù)-在組件實(shí)例進(jìn)入頁面節(jié)點(diǎn)樹時(shí)執(zhí)行) | |
ready | Function | 否 | 組件生命周期函數(shù)-在組件布局完成后執(zhí)行) | |
moved | Function | 否 | 組件生命周期函數(shù)-在組件實(shí)例被移動(dòng)到節(jié)點(diǎn)樹另一個(gè)位置時(shí)執(zhí)行) | |
detached | Function | 否 | 組件生命周期函數(shù)-在組件實(shí)例被從頁面節(jié)點(diǎn)樹移除時(shí)執(zhí)行) | |
relations | Object | 否 | 組件間關(guān)系定義,參見 組件間關(guān)系 | |
lifetimes | Object | 否 | 組件生命周期聲明對(duì)象,參見 組件生命周期 | 2.2.3 |
pageLifetimes | Object | 否 | 組件所在頁面的生命周期聲明對(duì)象,參見 組件生命周期 | 2.2.3 |
definitionFilter | Function | 否 | 定義段過濾器,用于自定義組件擴(kuò)展,參見 自定義組件擴(kuò)展 | 2.2.3 |
組件中使用
組件引用時(shí),在 behaviors
定義段中將它們逐個(gè)列出即可。
代碼示例:
// my-component.js var myBehavior = require('my-behavior') Component({ behaviors: [myBehavior], properties: { myProperty: { type: String } }, data: { myData: 'my-component-data' }, created: function () { console.log('[my-component] created') }, attached: function () { console.log('[my-component] attached') }, ready: function () { console.log('[my-component] ready') }, methods: { myMethod: function () { console.log('[my-component] log by myMethod') }, } })
在上例中, my-component
組件定義中加入了 my-behavior
,
而 my-behavior
結(jié)構(gòu)為:
- 屬性:
myBehaviorProperty
- 數(shù)據(jù)字段:
myBehaviorData
- 方法:
myBehaviorMethod
- 生命周期函數(shù):
attached
、created
、ready
這將使 my-component
最終結(jié)構(gòu)為:
- 屬性:
myBehaviorProperty
、myProperty
- 數(shù)據(jù)字段:
myBehaviorData
、myData
- 方法:
myBehaviorMethod
、myMethod
- 生命周期函數(shù):
attached
、created
、ready
當(dāng)組件觸發(fā)生命周期時(shí),上例生命周期函數(shù)執(zhí)行順序?yàn)椋?/p>
[my-behavior] created
[my-component] created
[my-behavior] attached
[my-component] attached
[my-behavior] ready
[my-component] ready
詳細(xì)規(guī)則參考 同名字段的覆蓋和組合規(guī)則。
同名字段的覆蓋和組合規(guī)則
組件和它引用的 behavior
中可以包含同名的字段,對(duì)這些字段的處理方法如下:
- 如果有同名的屬性 (properties) 或方法 (methods):
- 若組件本身有這個(gè)屬性或方法,則組件的屬性或方法會(huì)覆蓋 behavior 中的同名屬性或方法;
- 若組件本身無這個(gè)屬性或方法,則在組件的 behaviors 字段中定義靠后的 behavior 的屬性或方法會(huì)覆蓋靠前的同名屬性或方法;
- 在 2 的基礎(chǔ)上,若存在嵌套引用 behavior 的情況,則規(guī)則為:引用者 behavior 覆蓋 被引用的 behavior 中的同名屬性或方法。
- 如果有同名的數(shù)據(jù)字段 (data):
- 若同名的數(shù)據(jù)字段都是對(duì)象類型,會(huì)進(jìn)行對(duì)象合并;
- 其余情況會(huì)進(jìn)行數(shù)據(jù)覆蓋,覆蓋規(guī)則為: 引用者 behavior > 被引用的 behavior 、 靠后的 behavior > 靠前的 behavior。(優(yōu)先級(jí)高的覆蓋優(yōu)先級(jí)低的,最大的為優(yōu)先級(jí)最高)
- 生命周期函數(shù)和 observers 不會(huì)相互覆蓋,而是在對(duì)應(yīng)觸發(fā)時(shí)機(jī)被逐個(gè)調(diào)用:
- 對(duì)于不同的生命周期函數(shù)之間,遵循組件生命周期函數(shù)的執(zhí)行順序;
- 對(duì)于同種生命周期函數(shù)和同字段 observers ,遵循如下規(guī)則:
- behavior 優(yōu)先于組件執(zhí)行;
- 被引用的 behavior 優(yōu)先于 引用者 behavior 執(zhí)行;
- 靠前的 behavior 優(yōu)先于 靠后的 behavior 執(zhí)行;
- 如果同一個(gè) behavior 被一個(gè)組件多次引用,它定義的生命周期函數(shù)和 observers 不會(huì)重復(fù)執(zhí)行。
到此這篇關(guān)于微信小程序之behaviors的文章就介紹到這了,更多相關(guān)微信小程序behaviors內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript 實(shí)現(xiàn)頁面加載進(jìn)度條代碼
javascript 實(shí)現(xiàn)頁面加載進(jìn)度條代碼,需要的朋友可以參考下。2010-04-04鴻蒙JS實(shí)戰(zhàn)之計(jì)算器功能開發(fā)實(shí)例
這篇文章主要給大家介紹了關(guān)于鴻蒙Js實(shí)戰(zhàn)之計(jì)算器功能開發(fā)的相關(guān)資料,計(jì)算器是我們生活中經(jīng)常使用的應(yīng)用,此項(xiàng)目是基于Harmony實(shí)現(xiàn)的簡(jiǎn)易計(jì)算器,需要的朋友可以參考下2024-02-02微信小程序分享卡片花樣玩法之私密消息和動(dòng)態(tài)消息
用戶可以發(fā)送小程序卡片給微信好友或者群,點(diǎn)擊小程序卡片可以直接進(jìn)入小程序,這篇文章主要給大家介紹了關(guān)于微信小程序分享卡片花樣玩法之私密消息和動(dòng)態(tài)消息的相關(guān)資料,需要的朋友可以參考下2023-11-11pnpm install:ERR_PNPM_PEER_DEP_ISSUES Unmet p
這篇文章主要為大家介紹了pnpm install:ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies報(bào)錯(cuò)解決2023-06-06JavaScript前端實(shí)現(xiàn)GIF圖片循環(huán)播放
使用 img 加載 GIF 圖片,內(nèi)容只會(huì)播放一次,之后就會(huì)自動(dòng)暫停,所以這篇文章為大家介紹了如何使用JavaScript實(shí)現(xiàn)GIF圖片循環(huán)播放吧2025-03-03通過JS動(dòng)態(tài)創(chuàng)建一個(gè)html DOM元素并顯示
需要通過點(diǎn)擊某個(gè)元素后, 動(dòng)態(tài)創(chuàng)建一個(gè)DOM元素并顯示,因此寫了一些相關(guān)的js函數(shù),在此記錄下2014-10-10