美文网首页
微信小程序之watch属性值(仿Vue)

微信小程序之watch属性值(仿Vue)

作者: 5df463a52098 | 来源:发表于2019-03-05 16:03 被阅读4次

Vue通过监听watch属性来观测Vue实例数据的变化。

<template>
  <div>
    <el-input v-model="demo"></el-input>
    {{value}}
  </div>
</template>
<script>
  export default {
    name: 'index',
    data() {
      return {
        demo: '',
        value: '',
        childrens: {
            name: '小强',
            age: 20,
            sex: '男'
          },
      };
    },
    watch: {
      demo(val) {
        this.value = this.demo;
      },
      childrens:{
        handler:function(val,oldval){
          console.log(val.name)
        },
        deep:true//对象内部的属性监听,也叫深度监听
      },
      'childrens.name':function(val,oldval){
        console.log(val+"aaa")
      },//键路径必须加上引号
    }
  };
</script>

监听器的原理,将data中需监听的属性写在watch对象中,并给其提供一个方法,当被监听属性的值改变时,调用该方法。​​
微信小程序自定义watch属性,可以在qpp.js里定义,在页面onLoad里调用watch。

//app.js
App({
  /**
       * 设置监听器
       */
  setWatcher(page) {
    let data = page.data;
    let watch = page.watch;
    console.log(page)
    console.log(watch)
    Object.keys(watch).forEach(v => {
      let key = v.split('.'); // 将watch中的属性以'.'切分成数组
      let nowData = data; // 将data赋值给nowData
      for (let i = 0; i < key.length - 1; i++) { // 遍历key数组的元素,除了最后一个!
        nowData = nowData[key[i]]; // 将nowData指向它的key属性对象
      }
      let lastKey = key[key.length - 1];
      // 假设key==='my.name',此时nowData===data['my']===data.my,lastKey==='name'
      let watchFun = watch[v].handler || watch[v]; // 兼容带handler和不带handler的两种写法
      let deep = watch[v].deep; // 若未设置deep,则为undefine
      this.observe(nowData, lastKey, watchFun, deep, page); // 监听nowData对象的lastKey
    })
  },
  /**
   * 监听属性 并执行监听函数
   */
  observe(obj, key, watchFun, deep, page) {
    var val = obj[key];
    // 判断deep是true 且 val不能为空 且 typeof val==='object'(数组内数值变化也需要深度监听)
    if (deep && val != null && typeof val === 'object') {
      Object.keys(val).forEach(childKey => { // 遍历val对象下的每一个key
        this.observe(val, childKey, watchFun, deep, page); // 递归调用监听函数
      })
    }
    var that = this;
    Object.defineProperty(obj, key, {
      configurable: true,
      enumerable: true,
      set: function (value) {
        // 用page对象调用,改变函数内this指向,以便this.data访问data内的属性值
        watchFun.call(page, value, val); // value是新值,val是旧值
        val = value;
        if (deep) { // 若是深度监听,重新监听该对象,以便监听其属性。
          that.observe(obj, key, watchFun, deep, page);
        }
      },
      get: function () {
        return val;
      }
    })
  }
})

index.js里使用:

Page({
  data: {
    userInfo: {},
    my: {
      name: ''
    },
    your: {
      name: ''
    }
  },
  onLoad () {
    getApp().setWatcher(this)
    this.getUserInfo()
    this.data.my.name = "张三"
    this.data.your.name = "李四"
  },
  watch: {
// 方法一
    userInfo (newVal, oldVal) {
      console.log('111::',newVal)
    },
// 方法二
    'my.name' (newVal, oldVal) {
      console.log('222::',newVal)
    },
// 方法三
    your: {
      handler (newVal, oldVal) {
        console.log('333::',newVal)
      },
      deep: true
    }
  },
  getUserInfo () {
    wx.getUserInfo({
      success: (res) => {
        this.setData({
          userInfo: res.userInfo
        })
      }
    })
  }
})

相关文章

网友评论

      本文标题:微信小程序之watch属性值(仿Vue)

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