Vue双向数据绑定原理

1.双向数据绑定—前置技术点

1.1 数组的reduce()方法

应用场景:下次操作的初始值,依赖于上次操作的返回值

数组reduce方法,会循环当前的数组,侧重于进行“滚雪球”操作。
数组.reduce(函数,初始值)
const 累加结果 = 数组.reduce((上次计算结果,当前循环的Item项)=> {return 上次的结果 + 当前循环的Item项},0)

  • 1. 数值的累加计算
const total = arr.reduce((val,item)=>{return val+item},0)
  • 2. 链式获取对象属性的值
const obj = {
	name:'zy'
	info:{
		address:{
			location:'changsha'
			}
		}
  }
const attrs = ['info', 'address', 'location']
//第一次reduce,初始值是obj这个对象,当前Item项是info,结果是obj.info属性对应的对象
//第二次reduce,初始值是obj.info这个对象,当前Item项是address,结果是obj.info.address属性对应的对象
//第三次reduce,初始值是obj.info.address这个对象,当前Item项是location,结果是obj.info.address.location属性的值
//const location = attrs.reduce((newObj, key)=>{return newObj[key]}, obj)
const location = attrs.reduce((newObj, key)=> newObj[key], obj)
console.log(location) //changsha

//reduce链式获取对象属性值的升级操作,开发实际会用到
const attrStr = 'info.address.location'
attrStr.split(',').reduce((newObj, key)=> newObj[key], obj)

1.2 发布订阅模式

  1. Dep类:负责进行依赖收集,
    首先,有个数组专门存放所有的订阅信息
    其次,还要提供一个向数组中追加订阅信息的方法
    然后,还要提供一个循环,循环触发数组中的每个订阅信息
  2. Watcher类:负责订阅一些事件

比如说有个百货商店,有A B C三个顾客,A想买雪碧,B想买可乐,C想买芬达,但是恰好都卖完了,老板就说那你们在这个本子上留下电话号码,等到货了我打电话通知你们。ABC顾客离开了,将来到货老板拿着本子分别打电话,通知顾客来取东西,这就是发布订阅模式。

这个收集信息的本子相当于Dep类,到一定的时机,就会循环每一个订阅信息,通知到位。 顾客ABC相当于Watcher类,把自己的一些行为交给了Dep类,存放将来要做的事情,将来Dep发现时机到了,开始广播通知,把收集到的依赖都进行触发,那么Watcher类就收到了对应的消息。

Dep类负责收集+触发,所以它的身上有两个方法,一个是向数组里添加订阅,一个是循环数组里每一项来发布订阅。

只要我们为Vue中data数据重新赋值了,这个赋值的动作,会被vue监听到,然后vue要把数据的变化,通知到每个订阅者! 接下来,订阅者(每个DOM元素)要根据最新的数据,更新自己的内容。

1.3 使用Object.defineProperty()进行数据劫持

  • 通过get()劫持取值操作
  • 通过set()劫持赋值操作

2.Vue响应式原理

当一个vue实例创建时,vue会遍历data中对象所有的属性,使用Object.defineProperty(Vue3使用的是proxy)把这些属性全部转成getter / setter。 而每个组件实例都有Watcher对象,会在组件渲染的过程中把属性记录成依赖, 之后当依赖项的setter被调用时,会通知Watcher重新计算,从而使得关联的组件得以更新。
Vue双向数据绑定原理_第1张图片

3. 双向数据绑定原理

  • Observer对象:vue中数据对象在初始化过程中转换成Observer对象
  • Watcher对象:将模板和Observer对象结合在一起生成Watcher实例,Watcher是订阅者中的订阅者
  • Dep对象:Watcher对象和Observer对象之间的纽带,每一个Observer都有一个Dep实例,用来存储订阅者Watcher
  • 当属性变化会执行Observer的dep.notify方法,这个方法会遍历订阅者Watcher列表向其发送消息,Watcher会执行run方法去更新视图。模板编译过程中的指令和数据绑定都会生成Watcher实例,实例中的Watcher属性也会生成Watcher实例。

你可能感兴趣的:(前端知识,vue.js,javascript,前端)