双向绑定的原理及相关问题

双向数据绑定的原理

采用数据劫持结合发布者-订阅者模式的方式

data数据在初始化时,会实例化一个Observe类,它对data数据进行递归遍历,并通过Object.defineProperty方法,给每个值添加上一个gettersetter。在数据读取时,会触发getter进行依赖收集;在数据改变时,会触发setter,对刚收集的依赖进行触发,并且更新watcher,通知视图进行渲染。

使用 Object.defineProperty() 来进行数据劫持有什么缺点?

只能监听到数据的修改,监听不到数据的新增和删除,从而不能触发组件更新渲染。vue2中会对数组的新增删除方法push、pop、shift、unshift、splice、sort、reserve通过重写的形式,在拦截里面进行手动收集触发依赖更新。

和Vue3相比有什么区别?

Vue3采用了Proxy代理的方式,它提供了一个用于创建代理对象的构造函数。它对整个对象监听和拦截,可对对象所有操作进行处理。

Object.defineProperty只能监听单个属性的读写,无法监听新增、删除等操作。

Vue是如何收集依赖的?

依赖收集发生在defineReactive()方法中,在方法内new Dep()实例化一个Dep()实例,然后在getter中通过dep.depend()方法对数据依赖进行收集,然后在settter中通过dep.notify()通知更新。整个Dep是一个观察者,把收集的依赖存储起来,在需要的时候进行调用。在收集数据依赖的时候,会为数据创建一个Watcher,当数据发生改变通知每个Watcher,由Wathcer进行更新渲染。

data为什么是函数而不是对象?

data() { return {} }

  • 对象是引用类型的数据,当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会发生变化。
  • 在 Vue 中大多为了复用组件,当每次复用组件的时候,就会返回一个新的 data,那就需要每个组件都是私有数据空间,这样组件之间才不会相互干扰。它们各自维护自己的数据,不会干扰其他组件的正常运行。
  • 利用函数的格式,数据会以函数返回值的形式定义。

v-model 是如何实现的,语法糖是什么?

Vue 中数据双向绑定是一个指令v-model,可以绑定一个响应式数据到视图,同时视图的变化能改变该值。

  • 当作用在表单上:通过v-bind:value绑定数据,v-on:input来监听数据变化并修改value
  • 当作用在组件上:本质上是一个父子通信语法糖,通过props$emit实现。

语法糖写法:

完整写法:


你可能感兴趣的:(vue.js)