我们在面试的时候经常会被问到vue框架的原理类问题,我今天整理了一些常见问题和答案,希望有不正确之处还请指正。
首先实例化一个对象,该对象执行init方法初始化生命周期等等,随后执行$mount方法开始生成vnode和dom。其中el会作为根dom,然后会根据render生成vnode。
执行init方法
开始挂载
判断有无render函数,没有则会生成
h函数就是$createElement,调用该方法生成vnode
总结:new Vue时会触发vue的_init方法去初始化数据,将el作为根dom,然后调用$mount方法去挂载组件,挂载的过程中会执行_render方法生成vnode。
所谓的双向数据绑定就是当数据改变时视图也跟着变化,接下来我们看看关键代码。首先在get方法中会判断Dep.target是否存在,target是watcher实例,在视图中或者函数中获取该变量就会触发变量的get方法。然后该变量的dep实例就会放入当前的watcher(建立变量和watcher的联系)。
在set的时候,即数据发生修改的时候会执行当前变量的dep实例的notify方法,该方法会遍历执行当前观察的视图(所有的watcher)的update方法去异步更新视图。
总结:双向绑定的原理就是利用Object.defineProperty去设置变量的get和set方法,在该函数中会实例化dep数组。在获取数据的时候会触发变量的get方法去收集watcher,当变量发生改变时会触发变量的set方法去遍历dep数组,并执行watcher的update方法去刷新视图。
首先在init过程中会执行initProxy,在渲染的时候获取getA会从vm实例中获取getA:
我们再来看看computed的实现过程:
我们进入watcher看看,其中getter函数就是我们定义的computed函数getA。
在执行渲染函数的时候触发我们开头设置的proxy
createComputedGetter函数在init过程中定义
执行watcher的evaluate方法,此时调用get方法,该方法就是getA函数。
此时会触发变量的get方法去收集当前的Dep.target(computed的watcher实例)。所以当变量发生变化时会执行watcher的update方法。
computed还有缓存功能,当依赖不发生变化时是不会重新执行的,看如下代码dirty为false不会重新执行computed函数而是直接返回值。
从上面的分析可知会执行computed函数然后通知变量收集依赖,如果是异步函数那么返回的就是一个Promise,此时变量无法收集依赖,所以不支持异步也很好解释。
未完待续,持续更新。。。
上一篇:模板进阶篇
下一篇:SpringMVC获取请求参数