当前位置: 首页 > Web前端 > vue.js

Vue响应式原理概述

时间:2023-04-01 01:41:45 vue.js

1MVVM模式Model-View-ViewModel衍生自MVC模式,核心是ViewModel,ViewModel是一个“中转站”,连接到Model层获取和转换数据,使得View层的数据易于管理和易于使用。它还连接到视图层以进行双向数据绑定。MVVM框架使用ViewModel层来帮助开发人员完成以前jQuery时代搜索和操作DOM的低效工作。View最终展示的不仅仅是Model的数据,还有ViewModel处理后的数据。“虽然没有完全遵循MVVM模型,但Vue的设计也受到了它的启发。因此,文档中经常使用变量名vm(ViewModel的缩写)来表示组件实例。”2Vue双向数据绑定从设计思想上,Vue采用的MVVM模式是双向绑定。Vue实例作为MVVM中的ViewModel层,Model驱动View更新。View层模板编译完成后,Vue实例的内部数据也会随之更新。从开发者的角度来看,Vue并没有提供类似于AngularJS双向数据绑定的API。虽然它通过提供v-model这个语法糖来提供一些双向数据绑定的能力。Vue确实是一种单向数据驱动的视图。等同于3DataDrivenViewView是由数据驱动生成的,对于视图的修改不是直接操作DOM而是通过修改数据。通过使用虚拟DOM,Vue支持数据驱动的视图。看一下从创建Vue实例到最终渲染到页面的过程。如图:数据驱动视图生成流程:1)初始化Vue:Vue是一个类,newVue({...})操作调用构造函数完成merge配置,初始化生命周期,事件中心,初始化Injections,state(props|data|methods|computed|watch),provide等;2)将Vue实例挂载到el:验证页面上的挂载点el,得到对应的模板;3)模板编译:编译render()函数,经过一系列的compileToFunctions-createCompiler-createCompilerCreator,最后解析出ast,优化ast,最终生成render代码;4)调用render():将自定义配置中的数据与页面模板生成的数据结合后,生成VDOM;5)更新打补丁上一步中的VDOM输出DOM:patch提供了一个钩子函数,在回调中进行相应的处理生成DOM。4响应式原则响应式原则是指Vue中数据变化驱动的视图更新。实现中有两个关键点:1)将数据变成响应式数据;2)实施观察者模式:收集依赖关系和调度更新。响应式数据是指通过代理对象为数据添加getter和setter属性,使得对数据的访问和更新操作是可观察的。Vue2使用Object.defineProperty()方法,Vue3使用Proxy对象。然后通过观察者模式,在访问数据时收集依赖,当数据更新时通知之前收集的依赖进行更新处理。具体来说,在Vue内部,通过Observer类将数据递归转化为可观察对象,得到的响应式数据对象是一个包含__ob__属性的对象。在里面定义并调用一系列的处理函数:比如walk()\defineReactive()。依赖收集:在访问响应式数据触发getter函数时发生,收集的依赖是指渲染Watcher,收集动作的主体是响应式数据本身。具体来说,Vue内部实现了一个管理Watcher的Dep类(内部维护了一个数组),每个响应式数据对象属性值的getter持有对Dep的引用。当一个render调用完成后,所有响应数据的getter都会被触发,从而完成Watcher收集响应数据的过程。dispatchupdate:发生在更新响应数据触发setter函数时,其实就是将之前收集到的Watcher依赖从队列中取出,执行其update()方法的过程。其中,Vue也做了一些优化。不会在每次数据变化时触发watchers的回调执行。相反,这些观察者首先被添加到一个队列中,然后在nextTick之后执行flushSchedulerQueue,使用JavaScript提供的事件队列。异步执行更新操作。5Vue2和Vue3响应式原理的区别Vue2使用Object.defineProperty(),Vue3使用Proxy。与Object.defineProperty()相比,Proxy()不仅可以解决无法观察到对象属性增删改查的问题,也可以解决无法观察到数组的索引设置和长度变化的问题,而且它的API更加丰富。与Object.defineProperty()观察对象的属性相比,Proxy代表对象,性能更好。Object.defineProperty()不支持数组是因为Vue基于性能考虑是无用的,而不是因为它不支持它们。参考:Vue技术秘籍https://ustbhuangyi.github.io...https://www.cnblogs.com/iovec...