数据监听--watch实现(简易版)

watch 监听数据变化

使用这个属性,能够监视 data 中指定数据的变化,而后触发这个 watch 中对应的 function 处理函数函数

基本思路 --- Object.defineProperty()

getter:当获取(get)一个对象的某个属性时执行的方法ui

setter:当设置(set)一个对象的某个属性时执行的方法this

getter 和 setter 不须要咱们手动去调用,只要咱们对这个数据进行了操做,那这连个方法就会自动调用spa

(function () {
            var o = { a: 1}
            Object.defineProperty(o, 'b', {
                get: function() {
                    console.log('get') // 只有调用o.b时才会输出get
                    return this.a
                },
                set: function(val) {
                    this.a = val
                },
                configurable: true
            })
            // 此处虽然调用o.b,输出的倒是o.a的值
            console.log('a', o.a, 'b', o.b);  // a 1 b 1
            o.b = 2  // 给o.b赋值,实际上是赋值给了o.a
            console.log(o.a)  // 2
            // o始终只有a一个属性
            console.log(o)   // {a: 2}
        })()
复制代码

实现watch

// 定义watcher对象
        class watcher {
          constructor (opts) {
            this.$data = this.getBaseType(opts.data) === 'Object' ? opts.data : {}
            this.$watch = this.getBaseType(opts.watch) === 'Object' ? opts.watch : {}
            
            console.log(opts.data, opts.watch)
            // 遍历data的全部属性
            for (let key in opts.data) {
              console.log('key', key)  // key a key b
              this.setData(key, opts.data[key])
            }
          }
        
          getBaseType (target) {
            // 判断取数据类型
            const typeStr = Object.prototype.toString.call(target)
            return typeStr.slice(8, -1)
          }
        
          setData(_key, _value) {
            console.log(_key, _value)  // a 0 b hello
            // this: Object.defineProperty(this) 把上下文指向当前的对象
            Object.defineProperty(this, _key, {
              get: function () {
                console.log(_key)    // b a
                return this.$data[_key]
              },
              // val是新的值
              set: function (val) {
                console.log('val', val, '_value', _value);   // val 7 _value 0
                const oldVal = this.$data[_key]
                if (oldVal === val) return val  // 值相同,不更新
                this.$data[_key] = val  // 更新
                console.log(_key, this.$data[_key])  // a 7
                this.$watch[_key] && typeof this.$watch[_key] === 'function' && this .$watch[_key].call(this, val, oldVal)
                return val
              }
            })
          }
        }
        
        let vm = new watcher({
          data: {
            a: 0,
            b: 'hello'
          },
          watch: {
            // 处理函数
            // 一旦data.a的值发生改变则执行watch[a]()
            a(newVal, oldVal) {
              console.log('new', newVal, 'old', oldVal)  // new 7 old 0
            }
          }
        })
        
        console.log(vm.b)    // hello
        
        setTimeout(() => {
          console.log(vm.a = 7)  // 7
          console.log('vm.a', vm.a)  // vm.a 7
        }, 3000)
复制代码
输出:
    { a: 0, b: 'hello' } { a: [Function: a] }
    key a
    a 0
    key b
    b hello
    b
    hello
    ------------- 3s后 -------------
    val 7 _value 0
    a 7
    new 7 old 0
    7
    a
    vm.a 7复制代码
相关文章
相关标签/搜索