91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

小程序怎么通過watch和computed檢測數據

發布時間:2020-12-15 11:36:11 來源:億速云 閱讀:245 作者:小新 欄目:移動開發

小編給大家分享一下小程序怎么通過watch和computed檢測數據,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

在vue中,computed是一個計算屬性,類似于過濾器,對綁定到view的數據進行處理,并監聽變化。而watch監聽復雜數據類型需用深度監聽。這兩者都可以在vue上實現檢測數據的變化。而微信小程序不同于vue可以使用watch和computed做出相應的改變。小程序中只有函數this.setData()可以檢測數據,所以小程序每次數據改變需要檢測時都必須手動執行函數才可實現。除此之外,小程序還可以附上這兩個功能檢測數據變化。

vue 里是通過 Object.defineProperty 來實現數據變化檢測的,給該變量的 setter 里注入所有的綁定操作,就可以在該變量變化時帶動其它數據的變化。實際上,在小程序里實現要比 vue 里簡單,應為對于 data 里對象來說,vue 要遞歸的綁定對象里的每一個變量,使之響應式化。但是在微信小程序里,不管是對于對象還是基本類型,只能通過 this.setData() 來改變,這樣我們只需檢測 data 里面的 key 值的變化,而不用檢測 key 值里面的 key 。

測試代碼:

Page({
data: {
test: { a: 123 },
test1: \'test1\',
},
onLoad() {
computed(this, {
test2: function() {
returnthis.data.test.a + \'2222222\'
},
test3: function() {
returnthis.data.test.a + \'3333333\'
}
})
watch(this, {
test:function(newVal) {
console.log(\'invoke watch\')
this.setData({test1: newVal.a + \'11111111\' })
}
})
},
changeTest() {
this.setData({ test:{ a: Math.random().toFixed(5) } })
},
})

現在我們要實現 watch 和 computed 方法,使得 test 變化時,test1、test2、test3 也變化,為此,增加了一個按鈕,當點擊這個按鈕時,test 會改變。

watch 方法相對簡單點,首先我們定義一個函數來檢測變化:

function defineReactive(data, key, val, fn) {
Object.defineProperty(data, key, {
configurable: true,
enumerable: true,
get: function() {
return val
},
set: function(newVal){
if (newVal === val)return
fn &&fn(newVal)
val = newVal
},
})
}

然后遍歷 watch 函數傳入的對象,給每個鍵調用該方法

function watch(ctx, obj) {
Object.keys(obj).forEach(key => {
defineReactive(ctx.data, key, ctx.data[key], function(value) {
obj[key].call(ctx,value)
})
})
}

這里有參數是 fn ,即上面 watch 方法里 test 的值,這里把該方法包一層,綁定 context。

接著來看 computed,這個稍微復雜,因為我們無法得知 computed 里依賴的是 data 里面的哪個變量,因此只能遍歷 data 里的每一個變量。

function computed(ctx, obj) {
let keys =Object.keys(obj)
let dataKeys =Object.keys(ctx.data)
dataKeys.forEach(dataKey => {
defineReactive(ctx.data, dataKey, ctx.data[dataKey])
})
let firstComputedObj =keys.reduce((prev, next) => {
ctx.data.$target =function() {
ctx.setData({[next]: obj[next].call(ctx) })
}
prev[next] =obj[next].call(ctx)
ctx.data.$target =null return prev
}, {})
ctx.setData(firstComputedObj)
}

詳細解釋下這段代碼,首先給 data 里的每個屬性調用 defineReactive 方法。接著計算 computed 里面每個屬性第一次的值,也就是上例中的 test2、test3。

computed(this, {
test2: function() {
returnthis.data.test.a + \'2222222\'
},
test3: function() {
returnthis.data.test.a + \'3333333\'
}
})

這里分別調用 test2 和 test3 的值,將返回值與對應的 key 值組合成一個對象,然后再調用 setData() ,這樣就會第一次計算這兩個值,這里使用了 reduce 方法。test2 和 test3 都是依賴 test 的,這樣必須在 test 改變的時候在其的 setter 函數中調用 test2 和 test3 中對應的函數,并通過 setData 來設置這兩個變量。

小程序商店提供更多上線小程序

聲明了一個變量來保存所有在變化時需要執行的函數,在 set 時執行每一個函數,因為此時 this.data.test 的值還未改變,使用 setTimeout 在下一輪再執行。現在就有一個問題,怎么將函數添加到 subs 中。不知道各位還是否記得上面我們說到的在 reduce 里的那兩行代碼。因為在執行計算 test1 和 test2 第一次 computed 值的時候,會調用 test 的 getter 方法,此刻就是一個好機會將函數注入到 subs 中,在 data 上聲明一個 $target 變量,并將需要執行的函數賦值給該變量,這樣在 getter 中就可以判斷 data 上有無 target 值,從而就可以 push 進 subs,要注意的是需要馬上將 target 設為 null,

到此為止已經實現了 watch 和 computed,但是還沒完,有個問題。當同時使用這兩者的時候,watch 里的對象的鍵也同時存在于 data 中,這樣就會重復在該變量上調用 Object.defineProperty ,后面會覆蓋前面。因為這里不像 vue 里可以決定兩者的調用順序,因此我們推薦先寫 computed 再寫 watch,這樣可以 watch computed 里的值。

以上是“小程序怎么通過watch和computed檢測數據”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

抚州市| 梁河县| 镇康县| 郁南县| 内江市| 榆林市| 石河子市| 新绛县| 隆尧县| 石景山区| 新巴尔虎右旗| 耿马| 垫江县| 天台县| 新营市| 田林县| 泰和县| 锦屏县| 突泉县| 新平| 辉县市| 大化| 梅州市| 石阡县| 长子县| 枣庄市| 宁陵县| 嵩明县| 景洪市| 宁南县| 鹤庆县| 马公市| 长白| 称多县| 玛多县| 新乐市| 灌云县| 清苑县| 安达市| 关岭| 灵山县|