1 MVVM模式
Model-View-ViewModel源自MVC模式,外围是ViewModel,ViewModel作为一个“中转站”,对接Model层取得并转换数据使得数据易治理、便于View层应用,又对接View层进行双向的数据绑定。MVVM框架利用ViewModel这一层帮忙开发者们做好了之前jQuery时代低效的查找、操作DOM的工作。View最终展示的不仅是Model的数据,也是通过ViewModel加工后数据。
"尽管没有齐全遵循 MVVM 模型,然而 Vue 的设计也受到了它的启发。因而在文档中常常会应用 vm (ViewModel 的缩写) 这个变量名示意组件实例"
2 Vue双向数据绑定
从设计思维来说,Vue采纳的MVVM模式是双向绑定的。Vue实例即充当MVVM中ViewModel层,Model驱动View更新,View层模板进行编译后Vue实例外部数据也会更新。从开发者应用的角度来说,Vue并没有提供相似AngularJS双向数据绑定的API。尽管它通过提供v-model这个语法糖提供了局部双向数据绑定的能力。Vue实际上是单向的数据驱动视图。
<input v-model="inputData" />
等价于
<input :value="inputData" @input="inputData = $event.target.value"/>
3 数据驱动视图
视图是由数据驱动生成的,对视图的批改,不是间接操作DOM而是通过批改数据。通过利用虚构DOM,Vue实现了数据驱动视图。整体看一下从创立Vue实例到最初渲染到页面产生的过程。如图:
数据驱动生成视图的过程:
1)初始化Vue:Vue是一个类,new Vue({...})操作调用构造函数实现合并配置、初始化生命周期、事件核心,初始化Injections、state(props|data|methods|computed|watch)、provide等;
2)挂载Vue实例到el:校验页面上的挂载点el,并拿到对应的template;
3)模板编译:由template编译出render()函数,通过一系列的compileToFunctions-createCompiler-createCompilerCreator后,最初Parse出ast,通过优化ast,最终生成render代码;
4)调用render():将自定义配置中的数据和页面模板生成的数据联合后,生成VDOM;
5)update和patch上一步的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的收集的过程。
派发更新:产生在更新响应式数据触发setter函数时,实际上就是把之前收集好的Watcher依赖从队列中取出来执行其update()办法的过程。其中Vue也做了一些优化,并不会每次数据扭转都触发 watcher 的回调执行,而是把这些watcher先增加到一个队列里,而后在nextTick后执行 flushSchedulerQueue,利用JavaScript提供的事件队列的这种异步的形式执行更新动作。
5 Vue2和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...