10分钟读懂vue数据响应式和双向绑定原理

4,972 阅读3分钟

数据响应式和双向绑定在vue中是不同的概念

1. 数据响应式

数据响应式的作用是:数据驱动视图

1.1 数据响应式

Vue采用的是数据劫持结合发布和-订阅者模式的方式,通过拦截对数据的操作,在数据变动时发 布消息给订阅者,触发相应的监听回调。

1.2 数据劫持原理

vue2和vue3实现数据劫持的原理是不一样的

1.2.1 vue2数据劫持

vue2通过Object.definePropertydata上的数据递归地进行getter和setter操作,在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。也就是对属性的读取、修改进行拦截(数据劫持)

1.2.2 vue3数据劫持

vue3通过Proxy对象创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。Proxy的监听是深层次的,监听整个对象,而不是某个属性。

1.3 发布者-订阅者模式

简单地说,发布者-订阅者模式的流程就是,监听器监听数据状态变化, 一旦数据发生变化,则会通知对应的订阅者,让订阅者执行对应的业务逻辑 。

我们熟知的事件机制,就是一种典型的发布-订阅的模式。

首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发生变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer订阅者Watcher之间进行统一管理。接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图

  • 监听器Observer ,用来监听数据源变化.
  • 消息订阅器Dep,由于监听器和订阅者是一对多的关系,所以这里设计了一个管理中心,来管理某个监听器及其对应的订阅者的关系, 消息调度和依赖管理都靠它。
  • 订阅者Watcher,当某个监听器监听到数据发生变化的时候,这个变化经过消息调度中心,最终会传递到所有该监听器对应的订阅者身上,然后这些订阅者分别执行自身的业务回调即可

在这里插入图片描述

2. 双向绑定

双向绑定的作用是:数据和视图相互驱动更新,是相互影响的关系

2.1 v-model属性

vue中一般通过v-model体现双向绑定。

v-model实际上是v-onv-bind的语法糖。

针对于inputv-model双向数据绑定实际上就是通过子组件中的$emit方法派发input事件,父组件监听input事件中传递的值,并存储在父组件data中;然后父组件再通过prop的形式传递给子组件,在子组件中绑定inputvalue属性。

其他元素使用v-model双向数据绑定实际上就是,通过监听change事件。以及$emit方法派发,再通过prop的形式传递。

2.2 sync修饰符

父组件向子组件传递数据的方式有多种,props是其中的一种,但是由于单向数据流的原则,子组件不能直接修改prop属性

在这里插入图片描述

父组件中并没有定义过update事件,但是却可以完成prop属性page的修改,这就是sync语法糖的作用。

总结

数据响应式和双向绑定的主要区别在于

  • 数据响应式是数据驱动视图更新
  • 双向绑定是数据和视图相互驱动更新