W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
為了更好定制自定義組件的功能,可以使用自定義組件擴(kuò)展機(jī)制。
從小程序基礎(chǔ)庫(kù)版本 2.0.5 開(kāi)始支持。
為了更好的理解擴(kuò)展后的效果,在此舉例說(shuō)明:
代碼示例
在開(kāi)發(fā)者工具中打開(kāi)// behavior.js
module.exports = Behavior({
definitionFilter(defFields) {
defFields.data.from = 'behavior'
}
})
// component.js
Component({
data: {
from: 'component'
},
behaviors: [require('./behavior.js')],
ready() {
console.log(this.data.from) // 此處會(huì)發(fā)現(xiàn)輸出 behavior 而不是 component
}
});
通過(guò)例子可以發(fā)現(xiàn),自定義組件的擴(kuò)展其實(shí)就是提供了修改自定義組件定義段的能力。
Behavior() 構(gòu)造器提供了新的定義段 definitionFilter,用于支持自定義組件擴(kuò)展。 definitionFilter 是一個(gè)函數(shù),在被調(diào)用時(shí)會(huì)注入兩個(gè)參數(shù):
代碼示例
在開(kāi)發(fā)者工具中打開(kāi)// 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')]
});
說(shuō)明:
上述代碼中聲明了 1 個(gè)自定義組件和 3 個(gè) behavior,每個(gè) behavior 都使用了 definitionFilter 定義段。按照聲明的順序會(huì)有如下事情發(fā)生:
簡(jiǎn)單概括,definitionFilter 函數(shù)可以理解為當(dāng) A 使用了 B 時(shí),A 聲明就會(huì)調(diào)用 B 的 definitionFilter 函數(shù)并傳入 A 的定義對(duì)象讓 B 去過(guò)濾。此時(shí)如果 B 還使用了 C 和 D,那么 B 可以自行決定要不要調(diào)用 C 和 D 的 definitionFilter 函數(shù)去過(guò)濾 A 的定義對(duì)象。
下面利用擴(kuò)展簡(jiǎn)單實(shí)現(xiàn)自定義組件的計(jì)算屬性功能:
代碼示例
在開(kāi)發(fā)者工具中打開(kāi)// behavior1.js
module.exports = Behavior({
lifetimes: {
created() {
this._originalSetData = this.setData // 原始 setData
this.setData = this._setData // 封裝后的 setData
}
},
definitionFilter(defFields) {
const computed = defFields.computed || {}
const computedKeys = Object.keys(computed)
const computedCache = {}
// 計(jì)算 computed
const calcComputed = (scope, insertToData) => {
const needUpdate = {}
const data = defFields.data = defFields.data || {}
for (let key of computedKeys) {
const value = computed[key].call(scope) // 計(jì)算新值
if (computedCache[key] !== value) needUpdate[key] = computedCache[key] = value
if (insertToData) data[key] = needUpdate[key] // 直接插入到 data 中,初始化時(shí)才需要的操作
}
return needUpdate
}
// 重寫(xiě) setData 方法
defFields.methods = defFields.methods || {}
defFields.methods._setData = function (data, callback) {
const originalSetData = this._originalSetData // 原始 setData
originalSetData.call(this, data, callback) // 做 data 的 setData
const needUpdate = calcComputed(this) // 計(jì)算 computed
originalSetData.call(this, needUpdate) // 做 computed 的 setData
}
// 初始化 computed
calcComputed(defFields, true) // 計(jì)算 computed
}
})
// 在組件js中
const beh = require('./behavior1.js')
Component({
behaviors: [beh],
data: {
a: 0,
},
computed: {
b() {
return this.data.a + 100
},
},
methods: {
onTap() {
this._originalSetData({
a: ++this.data.a,
})
}
}
})
<!-- 在組件swan中 -->
<view>data: {{a}}</view>
<view>computed: {}</view>
<button bindtap="onTap">click</button>
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: