Fram/Lib

VUE2.0、VUE3.0响应式原理

字数:1385    阅读时间:7min
阅读量:6278

VUE2响应原理

VUE的一个特点就是数据响应式;当我们改变一个数据时,页面中所有用到该数据的地方都会发生改变;那么在这个过程中VUE都做了什么工作呢

  • 想要了解VUE如何实现响应式,可以从两个方面考虑
    1. 在改变数据的时候,VUE是如何知道数据变化的?(主要是通过Object.defineProperty()的getter和setter方法)
    2. 在知道数据变化之后,vue又是如何通知那些需要改变的数据进行改变的?(发布者订阅者模式)

我们可以简单模拟一下vue的响应式的核心代码

  • vue初始化状态的时候initData()函数用observer函数观测data数据变化(数据劫持,主要通过defindeProperty),每一个属性都有一个Dep实例用于搜集对应的依赖
  • 在模板编译时解析模板中的每一条指令,为每一条数据添加一个watcher对象,而每一个watcher又被添加到对应的Dep实例的subs订阅者列表里(触发getter方法),并初始化页面数据
  • 在改变数据的时候触发observer里的setter方法setter方法里又触发notify()通知所有watcher进行更新,在watcher函数里调用update()将数据更新到页面中去

vue2响应原理的缺点

  • data数据类型是Object对象时,使用defineProperty重写对象的getter和setter方法,通过getter搜集对应的依赖,通过setter触发所有的依赖;需要遍历所有的key属性,会有性能消耗问题(不能检测数据的新增和删除)
  • data数据类型为Array时,会拦截push、pop、shift、unshift、splice、sort、rever这些能改变原数组的方法来实现响应式,除了这些方法,改变数组的其他操作是不能被检测的;eg: array[0] = 0; array.length = 0

VUE3响应原理

vue3的响应原理与vue2大致是一样的都是类似于发布者订阅者模式;vue3改用了proxy代理方式实现,然后通过proxy的get方法里的track函数进行依赖搜集,通过set方法里的trigger进行触发依赖通知。

我们接下来通过简单实现vue3的reactive来了解一下vue3是如何进行响应式的

proxy的基本使用:

这里的Reflect是es6新增的一个对Object映射的一个内置对象。Reflect定义了Object上的十几种个静态拦截方法(get,set,construct,apply,has,ownKeys,defineProperty,deleteProperty,getOwnPropertyDescriptor,getPrototypeOf,setPrototypeOf,isExtensible,preventExtensions,setPrototypeOf)。使其有更好的规范性、易读性和扩展性。在es6中Reflect可以和proxy完美搭配使用。

reactive的简单实现:

reactive的简单完整实现 :

野生小园猿
励志做一只遨游在知识海洋里的小白鲨
查看“野生小园猿”的所有文章 →

相关推荐