Vue 检测数据

主要逻辑类似:

<script>
    let data = {
        name: 'name',
        address: 'address',
    };

    // 创建了一个监视对象,监视data属性的变化
    const obs = new Observer(data);

    let vm = {};
    vm._data = data = obs;

    function Observer(obj) {
        // 汇总对象所有的属性形成一个数组
        const keys = Object.keys(data);
        // 遍历
        keys.forEach((k) => {
            Object.defineProperty(this, k, {
                get(){
                    return obj[k];
                },
                set(val) {
                    obj[k] = val;
                    console.log(`数据${k}被修改,接下来解析模板,生成虚拟DOM,执行diff算法。。。`);
                },
            })
        })
    }
</script>

但是vue实现的更加强大复杂

  1. 通过数据代理实现 vm.name='xxx' 而不必 vm._data.name='xxx'
  2. 通过递归使得对于对象的属性也有 get set 方法

Vue.set()

代码运行时试图向对象中添加属性,vm._data.student.age=18添加的数据没有 get set 函数。

运行时添加对象属性应当使用 Vue.set(target, key, val)  例如 Vue.set(vm._data.persons, 'num',  3)简化方式 vm.$set(vm.persons, 'num', 3)

但是这个函数只能为 data 中的对象实例添加属性,不能为 vm._data 添加属性,即不能新增变量。

 

Vue 检测数据的数组处理

js中修改数组成员的函数:

  1. push
  2. pop
  3. shift
  4. unshift
  5. splice
  6. sort
  7. reverse

通过以上7个函数操作数组就有响应式结果。在vue中数组的 prototype 上有一个push等方法,它调用了原生Array的方法并进行了一些其他操作。这称为包装。

 


总结

  1. vue 会监测data中所有层次的数据
  2. 如何监测数据?
    1. 通过setter 实现监视,且要在 new Vue 时传入要监测的数据
    2. 对象中后追加属性,Vue默认不做响应式处理
    3. 如需添加属性做响应式,使用以下 API
      Vue.set(target, propertyName/index, value)
      vm.$set(target, propertyName/index, value)
  3. 如何监测数组中数据
    1. 通过包裹数组更新元素的方法实现,本质就是做两件事
    2. 调用原生对应的方法对数组更新
    3. 重新解析模板,进而更新页面
  4. 在Vue修改数组中某个元素一定要使用以下方法
    1. 7个修改数组的api方法
    2. Vue.set() 或 vm.$set()

不能给 vm 或 vm 的根数据对象添加属性

posted @ 2022-08-15 15:48  某某人8265  阅读(93)  评论(0编辑  收藏  举报