美文网首页
微信小程序实现watch监听

微信小程序实现watch监听

作者: 大海爱奔跑 | 来源:发表于2021-11-26 13:39 被阅读0次

    Vue.js里有watch监听机制,很适合“一处改变,多处影响”的场景,在开发小程序的过程中,自然也会遇到这样的场景,下面介绍如何在小程序中实现watch监听。

    1. 定义watch.js

    在根目录(miniprogram)下创建watch.js,代码如下:

    // watch.js
    
    const observe = (obj, key, watchFun, deep, page) => {
      let oldVal = obj[key]
      // 如果监听对象是object类型并且指定deep(深度监听)
      if (oldVal !== null && typeof oldVal === 'object' && deep) {
        // 递归子集,依次执行observe()
        Object.keys(oldVal).forEach(item => {
          observe(oldVal, item, watchFun, deep, page)
        })
      }
      // 使用Object.defineProperty()劫持数据的写操作,在监听对象改变后执行传入的watchFun
      Object.defineProperty(obj, key, {
        configurable: true,
        enumerable: true,
        set(value) {
          if (value === oldVal) return
          watchFun.call(page, value, oldVal)
          oldVal = value
        },
        get() {
          return oldVal
        }
      })
    }
    
    export const setWatcher = (page) => {
      // 页面里的data字段
      const data = page.data
      // 页面里的watch字段
      const watch = page.watch
      // 对watch里列举的每一个字段(需要监听的字段)执行observe()
      Object.keys(watch).forEach(key => {
        let targetData = data
        const targetKey = key
        // 支持deep深度监听,使用deep时需要配合handler使用,否则直接编写函数
        const watchFun = watch[key].handler || watch[key]
        const deep = watch[key].deep
        observe(targetData, targetKey, watchFun, deep, page)
      })
    }
    

    2. 使用方法

    在需要使用监听机制页面的js文件(如index.js)onLoad钩子里,执行setWatch(使用import关键词从watch.js引入),并传入当前页面实例this,完成初始化。

    添加watch对象,内部写入需要被监听的字段以及执行函数:

    // index.js
    
    import { setWatch } from '../../watch.js'
    
    Page({
      data: { ... },
      watch: {
        // 需要监听的字段
        foo(val) {
          console.log('foo变化了,变化后的值是', val)
          ... // 具体操作
        }
      },
      // watch初始化,传入当前页面实例this
      onLoad() {
        setWatch(this)
      }
    })
    

    相关文章

      网友评论

          本文标题:微信小程序实现watch监听

          本文链接:https://www.haomeiwen.com/subject/ofztxrtx.html