Vue深入响应式原理

Vue响应式:数据发生变化,会重新渲染页面

完成这个过程,我们需要:

  • 侦查数据的变化 数据劫持 / 数据代理
  • 收集视图依赖的数据 依赖收集
  • 数据变化时,自动通知需要更新的视图部分进行更新 发布-订阅模式

一、如何侦查数据的变化 - 数据劫持

使用Object.definePropertyProxy

  • 数据模型是普通的js对象,把一个普通的js对象传入Vue实例当作data选项,Vue会遍历此对象的property,并使用Object.defineProperty把property全部转为getter/setter
  • Vue通过设定对象属性的getter/setter方法来监听数据变化,通过getter进行依赖收集,每个setter方法就是一个观察者,数据变更时通知订阅者更新视图

二、为什么要收集视图依赖 - 依赖收集

通过收集依赖才能知道哪些地方依赖此数据,以及数据更新和派发更新。
核心思想:事件发布-订阅模式
重要角色:订阅者Dep和观察者Watcher

订阅者Dep

  1. 为什么引入Dep
    收集依赖、删除依赖和向依赖发送消息
  2. 简单实现
class Dep{
	constructor(){
		// 保存watcher对象的数组
		this.arr = []
	}
	 // 在arr 数组中添加一个watcher对象
	 addArr(obj){
		 this.arr.push(obj)
	 }
	 // addArr方法:Dep对象中增加Watcher的订阅操作
	 // 通知所有watcher对象更新视图
	 notify(){
	 	this.arr.forEach((obj)=>{obj.update()})
	 }
	 // 通知目前Dep对象的arr中的所有Watcher对象触发更新操作
}

当需要依赖收集的时候调用addArr方法,需要派发更新消息调用notify()

观察者Watcher

1.为什么引入Watcher
当属性发生变化时,我们要通知用到此数据属性的地方,而使用此数据的地方很多且类型不一样,需要抽象出一个类集中处理这些情况,然后在依赖收集阶段只收集这个封装好的实例,通知也只需要通知这一个,然后它在负责通知其他地方

在这里插入图片描述

2.Watcher简单实现

收集依赖

在getter中收集依赖,在setter中触发依赖

当外界通过Watcher读取数据时,便会触发getter将Watcher添加至依赖中,将触发getter的Watcher收集到Dep中,当数据发生变化时,会循环依赖列表,遍历所有的Watcher

在这里插入图片描述

  • new Vue创建vue实例后,Vue调用_init函数进行初始化,此时Data通过Observer转换为setter/getter形式,追踪数据的变化。当外界读取数据时触发getter函数,而当被赋值的时候执行setter函数
  • 当Render Function执行时,读取对象的值触发getter函数从而将Watcher添加至依赖中,进行依赖收集
  • 修改对象值的时候,触发setter函数,setter通知之前收集依赖得到的订阅者Dep中的每一个Watcher,通知组件更新。此时Watcher开始调用update更新视图
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值