vue响应式原理

文章详细解析了Vue如何利用Object.defineProperty进行数据劫持,并结合发布订阅模型实现双向绑定。重点介绍了Observer、Watcher和Dep的角色,以及computed和watch的监听机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解释

Vue 双向绑定的底层原理主要利用了 Object.defineProperty() 和 发布订阅模型。

首先,Vue 使用 Object.defineProperty() 进行数据劫持,即每当尝试访问或者修改一个数据属性时,都会触发一个 setter 或 getter 函数。这些函数负责通知 Vue 实例关于数据变化的消息。

其次,当数据发生变化时,Vue 又会采用发布订阅模型来传递数据变更的信息。当一个数据发生变化时,Vue 实例内的 watcher 监听器就会被触发,然后它会通知对应的子组件或者其他相关的 watcher 监听器。 这两种机制共同构成了 Vue 的双向绑定底层原理,使得数据变化能够及时反应到视图层。

Watcher

Observer 是 Vue.js 中用来监控数据变动的一个类,当数据发生变动时,Observer 会触发相应的监听器,进行相应的数据更新。而 Watcher 是一个实例化后的 Observer,它可以注册一些监听器,当数据变动时,Watchers 就会触发这些监听器,并通知相应的组件更新视图。

当 Vue.js 挂载实例时,会自动创建一个根级别的 Observer,并为其关联到 Vue 实例的 data 对象。这个 Observer 会遍历 Vue 实例的所有 data 属性,为每个属性创建一个 Watcher,并添加到 Watcher 集合中。当数据发生变动时,Observer 就会触发相应的 Watcher 进行更新。

Vue 实例中并没有固定的 Watcher 数量,而是取决于具体的业务需求和使用的组件数量。Watcher 是 Vue 自动为响应式数据绑定提供的观察者对象,Vue 会在组件的 props data 上创建 Observer 对象,以便监控它们的变化。 一般来说,Vue 实例内有多少个需要监控的数据属性,就会有多少个 Watcher 对象。除此之外,Vue 还会为 computed 属性、watch 函数以及其他一些配置项(如 directives、filters 等)创建额外的 Watcher 对象。

Observer、Watcher和Dep的关系

Observer:观察者主要负责依赖收集和触发相应的变化。在Vue中,每个依赖项(Dep)都会有一个对应的观察者(Observer)。当你把一个普通的数据对象传入Observer,它会自动找出数据对象中所有可响应的属性,并给这些属性添加getter和setter。当数据发生改变时,getter和setter会自动触发,观察者会收集所有依赖该数据的Dep,并将其添加到当前作用域下的 Dependents 数组中,并触发相应的变化。

Dep:依赖项(Dep)是Vue响应式系统中的关键概念之一,它负责收集所有依赖当前数据的 Watcher 对象。Dep对象表示一个依赖关系,它可以是单个变量、数组或对象属性等。当Dep所依赖的数据发生改变时,Dep会通知其相关的Watcher进行更新。

Watcher:Watcher是一个实例化后的 Observer,它继承了Observer的特性,并且它自己还有一个队列(watcher queue)。Watcher通常与一个Dep对象关联,当依赖项的值发生变化时,Watcher会调用相应的回调函数,更新自身的依赖列表,并调用 update 方法来更新视图。Watcher可以是异步的,允许对Dep的变化进行批量处理。

总的来说,Vue.js 的三大核心组件分别是 Observer、Watcher 和 Dep,Observer 负责检测数据变化,Dep 维护了依赖关系,而 Watcher 触发视图的更新。它们协同工作,实现了数据的即时更新和双向绑定的功能。

computed是怎么实现缓存的

通过 watcher.dirty 控制是否读取缓存。

watch是怎么监听的

Vue.js 会将需要监听的变量存储在一个 Dep(Dependency)对象中,当 Dep 对象发生变化时,Vue.js 就会通知 Watcher 进行更新。而在 Watcher 中,Vue.js 会记录每次数据变化的时间戳,然后在下一次数据变化时,比较这两个时间戳的差异,从而判断出是否需要更新视图。它默认是监听引用地址,若加上deep,watch 便使用 Object.defineProperty() 来定义监听器。

总结

Watcher 是 Vue 实现双向数据绑定的关键组件。实际上所有监听原理的实现都是Dep对象与Watcher对象建立联系,在Dep对象对应属性改变时触发视图更新,从而运行相关逻辑。

vue选项中props、data、computed、watch都是通过Object.defineProperty进行数据拦截从而实现响应式。watch是监听key(watch下的key必须是被数据拦截的属性),对应一个watcher对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值