小程序中使用watch Ⅱ,已封装完成

在上一篇watch详解中解释了watch 的原理   链接

这次是我抽空完整封装好的demo

效果:

页面中代码写法:

函数触发前:

函数触发后:

具体效果描述:写法与vue中的写法相同,个人做了单向绑定,修改被监听的参数,会同步到视图层

如何使用

1.在项目文件目录下创建一个存储外部脚本的文件夹  例:single

2.创建一个js文件,并且写入以下代码 例:watch.js

写入代码

let singlever = {
    watch(_this,state) {
        if (!_this) { throw 'page对象不存在' }
        let subsitute = {}
        let watchFunc = _this.watch
        if(watchFunc.constructor === Function){     //非page构造
            console.info('非Page页面,使用组件加载模式')
            watchFunc = _this.watch()
        }
        Object.keys(watchFunc).some(item => {
        //创建缓存监听get初始化数据
        subsitute[item] = _this.data[item]
        if(watchFunc[item].constructor === Object){
                console.log('数据为object')
                Object.defineProperty(_this.data, item, {
                    set: function (val) {
                        if (subsitute[item] === val) { return }
                        subsitute[item] = val
                        watchFunc[item].set(val,_this)
                    },
                    get:watchFunc[item].get(_this)
                })
            }else{
                Object.defineProperty(_this.data, item, {
                    set: function (val) {
                        if (subsitute[item] === val) { return }
                        subsitute[item] = val
                        watchFunc[item](val,_this)
                    },
                    get(){
                        return subsitute[item]
                    }
                })
            }
        })
    }
}
 
module.exports = singlever

3.在小程序入口js文件 app.js 文件中引入 

4.对其进行封装

5.封装完毕后,可对其进行调用,因为不同类型的页面构造函数不一样,所以引入的写法不一样,

(所有的页面都要先通过getApp函数获取的App对象再调用其封装的方法)

正常的Page中:

推荐在onLoad中调用

  onLoad: function (options) {
    const app = getApp()
    app.watch(this)
  },

完整的写法 在Page构造的页面中watch的写法和vue一样,与data同级

const app = getApp()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    aaa: 123
  },
  watch:{
    aaa(val){
      console.log('page函数',val)
    }
  },
  onLoad: function (options) {
    app.watch(this)
  },
  onShow: function () {

  },
})

组件Component中写法:

推荐在ready中调用

  ready(){   //类似于beforeMounted 组件挂载前
    const app = getApp()
    app.watch(this)
  },

完整的写法 在Component构造的组件页面中,需要将 watch 以函数的形式写入到 methods 中,并且用return返回

const app = getApp();
Component({
  data:{
    lll:123,
  },
  methods: {
    watch(){
      return{
        lll(val){
          console.log('lll改变成功')
        }
      }
    },
  },
  ready(){   //类似于beforeMounted 组件挂载前
    app.watch(this)
  },
})

//2020 6 .2 更新

修复了页面 watch 对象中,没有 this 指向当前页面的 bug,

当前页面对象 在被监听函数的第二个参数传入 例如:

  watch:{
    date(val,_this){
      console.log(_this)
    }
  },

输出当前页面对象

最关键可以使用 _this.setData({})  将未被监听的数据,同步到视图层

//2020 6 11更新

在 Component 组件中,监听之后的数据将无法使用 this.data.xxx 来读取到该数据

暂无解决方法 ,组件中慎用监听

//2021 7.19更新(undefined问题解决

问题在于使用 defineProperty 重构对象属性的get,set之后,get方法默认会返回undefined,所以导致之前可以正常修改属性,触发set,但获取值的时候为undefined
重新正确构写get之后监听使用正常

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值