Vue监视测数据的原理

250 阅读1分钟
  1. 响应式加工data
  2. vm._data = data

检测对象

let data = {
        name: "shangguigu",
        address: "beijing"
    }
    // 创建一个监视的实例对象,用于监视data中属性的变化
    const obs = new Observer(data)
    console.log(obs);

    // 准备一个vm实例对象
    let vm = {}
    vm._data = data = obs

    function Observer(obj) {
        //汇总对象中所有的属性形成一个数组
        const keys = Object.keys(obj);
        //遍历数组
        keys.forEach((k) => {
            Object.defineProperty(this, k, {
                get() {
                    return obj[k]   //把传入对象的k对应的值传出去
                },
                set(val) {
                    console.log(`${k}被改了,要去解析模板,生成虚拟dom...`);
                    obj[k] = val    //收到new val,改传入对象的k对应的属性改掉

                }
            })
        })
    }

通过setter实现,且在new Vue的时候就传入要监测的数据

data代码完成后想要再给data里面的对象添加属性,调用以下两个api,其他方法无法实现响应式,回调函数也是用它

vue.set(vm.student,'sex','女')

vm.$set(vm.student,'sex','男')

但是不能给data本身或vm本身添加属性

检测数组

直接通过索引值修改数组的话,Vue不会承认修改

需要使用push、splice、shirft、sort、reverse等数组常用方法才会被检测到

filter不是,他是直接return个新的数组

这些方法已经被Vue包装过(先调用院方法,再重新解析模板)

其实这样也可以被检测到vue.set(vm.hobby,1,‘打球’)

数据劫持:如果有人修改data:{}中的属性,set马上就能劫持到(什嘛玩意)

数据劫持和数据代理都用的是Object.defineProperty