国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 熱點 > 微信 > 正文

在微信小程序里使用watch和computed的方法

2024-07-22 01:17:29
字體:
來源:轉載
供稿:網友

在開發 vue 的時候,我們可以使用 watch 和 computed 很方便的檢測數據的變化,從而做出相應的改變,但是在小程序里,只能在數據改變時手動觸發 this.setData() ,那么如何給小程序也加上這兩個功能呢?

我們知道在 vue 里是通過 Object.defineProperty 來實現數據變化檢測的,給該變量的 setter 里注入所有的綁定操作,就可以在該變量變化時帶動其它數據的變化。那么是不是可以把這種方法運用在小程序上呢?

實際上,在小程序里實現要比 vue 里簡單,應為對于 data 里對象來說,vue 要遞歸的綁定對象里的每一個變量,使之響應式化。但是在微信小程序里,不管是對于對象還是基本類型,只能通過 this.setData() 來改變,這樣我們只需檢測 data 里面的 key 值的變化,而不用檢測 key 值里面的 key 。

先上測試代碼

<view>{{ test.a }}</view><view>{{ test1 }}</view><view>{{ test2 }}</view><view>{{ test3 }}</view><button bindtap="changeTest">change</button>
const { watch, computed } = require('./vuefy.js')Page({ data: {  test: { a: 123 },  test1: 'test1', }, onLoad() {  computed(this, {   test2: function() {    return this.data.test.a + '2222222'   },   test3: function() {    return this.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)}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 江川县| 奉化市| 邢台市| 临泽县| 阳春市| 得荣县| 民丰县| 保靖县| 无棣县| 郑州市| 大同县| 巍山| 徐水县| 九龙坡区| 龙川县| 英吉沙县| 城口县| 交口县| 武鸣县| 通化县| 楚雄市| 山阴县| 沁水县| 南汇区| 郓城县| 湛江市| 元朗区| 哈巴河县| 宿松县| 平南县| 崇仁县| 山阳县| 疏附县| 丹棱县| 连平县| 东光县| 通许县| 莎车县| 九台市| 东明县| 虎林市|