Vue.js变化侦测

一、Object的变化侦测

vue通过Object.definProperty将对象的key转换成getter/setter的形式来追踪变化,但是getter/setter只能追踪数据是否被修改,无法追踪新增属性和删除属性。

为了解决这个问题,vue也提供了两个API:

  • vm.$set
  • vm.$delete

如下面这个demo:

<template>
    <div>
        <button @click="action">objAddName</button>
        <button @click="deleteBarName">deleteBarName</button>
        <p v-if="obj.name">{{ obj.name }}</p>
        <p>{{ bar.name }}</p>
    </div>
</template>

<script>
export default {
    name: '',
    data() {
        return {
            obj: {},
            bar: {
                name: 'this is bar.name'
            }
        }
    },

    methods: {
        action() {
            this.obj.name = 'obj.name'; // 该操作不会被侦测到
        },

        deleteBarName() {
            delete this.bar.name        // 该操作不会被侦测到
        }
    }
}
</script>

读取数据的时候,getter会被触发,然后进行依赖收集,收集了依赖之后还需要将依赖存储起来,以备使用。

当数据发生变化的时候,触发setter,然后循环依赖列表,把所有的watcher都通知一遍。

 

 

二、Array的变化侦测

Array的变化侦测和Object不一样,Array是通过数组的方法来改变内容的,所以对Array的变化侦测是采用创建拦截器去覆盖原型中的方法的形式来追踪变化。

Array收集依赖的方式和Object一样,都是在getter中收集,但是依赖的存储位置是不同的;因为数组要在拦截器中向依赖发消息,所以不能像Object那样保存在definReactive中,而是把依赖保存在了Observer实例上。

 

但也因为Array的变化侦测方式上的原因,有一些方法导致数组发生变化也是无法侦测到的,如:

this.arr[0] = 1;
this.arr.length = 0;

像这样的操作,并不是通过数组的方法来改变数组本身,是不会被vue侦测到的。

数组的方法中,有7个方法可以改变数组本身:

  • push
  • pop
  • unshift
  • shift
  • splice
  • sort
  • reverse

上面这7个方法都是被新创建的拦截器所拦截了的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值