欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

在小程序中實現(xiàn) watch - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

您當前位置>首頁 » 新聞資訊 » 小程序相關(guān) >

在小程序中實現(xiàn) watch

發(fā)表時間:2021-1-11

發(fā)布人:葵宇科技

瀏覽次數(shù):49

微信小程序官方?jīng)]有提供 watch,用來監(jiān)聽 data 中的屬性的變化

日常開發(fā)中如果少了 watch,會顯得束手束腳

ES5 提供了 Object.defineProperty() 的方法,通過 getter/setter 劫持對象,實現(xiàn)在賦值時調(diào)用 setter 方法,執(zhí)行 watch 中對應的方法,從而實現(xiàn)監(jiān)聽。

設置監(jiān)聽者

setWatcher 函數(shù)遍歷會遍歷 data 中的所有屬性,給沒有一個屬性添加一個監(jiān)聽器 observe

const setWatcher = (page) => {
  const data = http://www.wxapp-union.com/page.data
  const watch = page.watch
  Object.keys(watch).forEach(key => {
    let targetData = http://www.wxapp-union.com/data
    const targetKey = key
    const watchFun = watch[key].handler || watch[key]
    const deep = watch[key].deep
    observe(targetData, targetKey, watchFun, deep, page)
  })
}
復制代碼

實現(xiàn)監(jiān)聽器

observe 函數(shù)接收 5 個參數(shù)

  • paga 中的 data
  • data 中的屬性 key
  • watch 中的函數(shù)
  • 是否要對 data 中的屬性進行深度監(jiān)聽
  • page,會被傳遞到監(jiān)聽函數(shù)中

如果 deep 為 true 需要深度監(jiān)聽,遞歸調(diào)用 observe,實現(xiàn)深度監(jiān)聽

使用 Object.defineProperty 的 setter 方法攔截外部對 data 數(shù)據(jù)的處理,同時調(diào)用 watchFn 實現(xiàn)監(jiān)聽。

watchFn 接收兩個參數(shù),value 和 oldValue,使用 call 將 page 傳遞進去。使 watch 中可以正常使用 page(this)

/**
 * 
 * @param {Object} obj  // data
 * @param {String} key  // data 屬性
 * @param {Fucntion} watchFun  // 監(jiān)聽函數(shù)
 * @param {Boolean} deep // 是否深度監(jiān)聽
 * @param {Object} page  // page 
 */
const observe = (obj, key, watchFn, deep, page) => {
  let oldVal = obj[key]
  if (oldVal !== null && typeof oldVal === 'object' && deep) {
    Object.keys(oldVal).forEach(item => {
      observe(oldVal, item, watchFun, deep, page)
    })
  }
  Object.defineProperty(obj, key, {
    configurable: true,
    enumerable: true,
    set(value) {
      if (value =http://www.wxapp-union.com/== oldVal) return
      watchFn.call(page, value, oldVal)
      oldVal = value
    },
    get() {
      return oldVal
    }
  })
}
復制代碼

注意事項:

  • watch 只能監(jiān)聽已存在的屬性,數(shù)組的 pop() 和 push() 等方法不會觸發(fā)
  • 一開始不在 data 中的屬性,后續(xù)動態(tài)添加的屬性也不會觸發(fā)

完整代碼

const observe = (obj, key, watchFun, deep, page) => {
  let oldVal = obj[key]
  if (oldVal !== null && typeof oldVal === 'object' && deep) {
    Object.keys(oldVal).forEach(item => {
      observe(oldVal, item, watchFun, deep, page)
    })
  }
  Object.defineProperty(obj, key, {
    configurable: true,
    enumerable: true,
    set(value: any) {
	  if (value =http://www.wxapp-union.com/== oldVal) return
      watchFun.call(page, value, oldVal)
      oldVal = value
    },
    get() {
      return oldVal
    }
  })
}

export const setWatcher = (page) => {
  const data = http://www.wxapp-union.com/page.data
  const watch = page.watch
  Object.keys(watch).forEach(key => {
    let targetData = http://www.wxapp-union.com/data
    const targetKey = key
    const watchFun = watch[key].handler || watch[key]
    const deep = watch[key].deep
    observe(targetData, targetKey, watchFun, deep, page)
  })
}
復制代碼

使用

import {  setWatcher} from "/utils/watch.js"

Page({
  data: {
    age: 12,
      person: {
        name: 'uccs'
      }
  },
  onLoad() {
    setWatcher(this)
  },
  watch: {
    age(val) {
      console.log(val)
    },
    person: {
      deep: true,
      handler(val) {
        console.log(val)
      }
    }
  },
  onClick() {
    this.data.age = 18
    this.data.person.name = 'tiantian'
  }
})
復制代碼

相關(guān)案例查看更多