既然小程序的組件已經(jīng)有Observer功能,那為什么還要手寫watch功能呢?
- Observer只能在Component中使用,沒法在Page中使用。若是想在Page中監(jiān)控某一數(shù)據(jù)的變化,Observer做不到。
- Observer屬于小程序的新功能,只能在高版本微信使用,低版本微信無法使用。公司的小程序就因?yàn)槭褂昧薕bserver功能,導(dǎo)致很多低版本微信用戶無法使用這個(gè)小程序。
?HTML代碼
<view>{{n1}}+{{n2}}={{sum}}</view>
<button bindtap="addn1">頁面中監(jiān)聽n1+1</button>
<button bindtap="addn2">頁面中監(jiān)聽n2+1</button>
新建一個(gè)watch.js文件存放監(jiān)聽器的邏輯函數(shù),代碼如下:
/**
* 設(shè)置監(jiān)聽器
*/
export function setWatcher(page) {
let data = page.data;
let watch = page.watch;
Object.keys(watch).forEach(v => {
let key = v.split('.'); // 將watch中的屬性以'.'切分成數(shù)組
let nowData = data; // 將data賦值給nowData
for (let i = 0; i < key.length - 1; i++) { // 遍歷key數(shù)組的元素,除了最后一個(gè)!
nowData = nowData[key[i]]; // 將nowData指向它的key屬性對(duì)象
}
let lastKey = key[key.length - 1];
let watchFun = watch[v].handler || watch[v]; // 兼容帶handler和不帶handler的兩種寫法
let deep = watch[v].deep; // 若未設(shè)置deep,則為undefine
observe(nowData, lastKey, watchFun, deep, page); // 監(jiān)聽nowData對(duì)象的lastKey
})
}
/**
* 監(jiān)聽屬性 并執(zhí)行監(jiān)聽函數(shù)
*/
function observe(obj, key, watchFun, deep, page) {
var val = obj[key];
// 判斷deep是true 且 val不能為空 且 typeof val==='object'(數(shù)組內(nèi)數(shù)值變化也需要深度監(jiān)聽)
if (deep && val != null && typeof val === 'object') {
Object.keys(val).forEach(childKey => { // 遍歷val對(duì)象下的每一個(gè)key
observe(val, childKey, watchFun, deep, page); // 遞歸調(diào)用監(jiān)聽函數(shù)
})
}
Object.defineProperty(obj, key, {
configurable: true,
enumerable: true,
set: function(newVal) {
watchFun.call(page, newVal, val);
val = newVal;
if (deep) { // 若是深度監(jiān)聽,重新監(jiān)聽該對(duì)象,以便監(jiān)聽其屬性。
observe(obj, key, watchFun, deep, page);
}
},
get: function() {
return val;
}
})
}
module.exports = {
setWatcher: setWatcher
}
?在該文件中引入watch.js,
???tips:如果有多個(gè)頁面都需要使用watch監(jiān)聽,可以直接在app.js中引入該文件,注冊(cè)成全局函數(shù),這樣就不用每個(gè)文件都去引入watch.js了,只需要在使用的頁面onLoad的時(shí)候調(diào)用一次該函數(shù),就能愉快的使用watch了。文章來源:http://www.zghlxwxcb.cn/news/detail-771768.html
import { setWatcher } from '../../utils/watch';
?js代碼文章來源地址http://www.zghlxwxcb.cn/news/detail-771768.html
data: {
n1:1,
n2:0,
sum:0,
obj: {},
},
addn1(){
this.setData({
n1:this.data.n1+1,
})
},
addn2(){
this.setData({
n2:this.data.n2+1,
})
},
onLoad(options) {
// 在onload的時(shí)候調(diào)用一次監(jiān)聽函數(shù),然后就可以像vue一樣愉快的使用watch了
setWatcher(this);
},
// 用法完全和vue一樣,也能實(shí)現(xiàn)對(duì)象的深度監(jiān)聽
watch: {
n1(n1) {
console.log(n1)
this.setData({
sum:n1+this.data.n2
})
},
n2(n2) {
console.log(n2)
this.setData({
sum:n2+this.data.n1
})
},
obj: {
handler(v) {
console.log(v)
},
deep: true
}
},
到了這里,關(guān)于微信小程序?qū)崿F(xiàn)頁面數(shù)據(jù)偵聽器,類似vue的watch的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!