请简述 Vue 首次渲染的过程。
-
Vue初始化,实例成员、静态成员
首先进行vue的初始化,即初始化实例成员及静态成员。 -
new Vue()
初始化结束以后,调用vue的构造函数new Vue(),在构造函数中调用this._init()方法。 -
this.init()
this.init()相当于整个项目的入口,在这个方法中,最终调用vm.$mount()。 -
vm.$mount()
这个mount()是src/platform/web/entry-runtime-with-compiler.js中定义的,核心作用是把模板编译为render函数,判断是否有render选项,如果没有,则会获取template选项,如果template也没有,会把el中的内容作为模板,通过compileToFunctions()方法将模板编译为render函数,编译好以后,将render存入到options.render中。 -
**vm.mount()中重新获取el。
-
mountComponent(this,el)
这个方法在src/core/instance/lifecycle.js中定义的,首先判断是否有render选项,如果没有但是传入了模板,并且当前是开发环境,则发出警告(运行时版本不支持编译器),触发beforeMount钩子函数(开始挂载之前),定义updateComponents函数但是并未调用,这个函数中调用render()和update()两个方法,render是生成虚拟dom,update是将虚拟dom转化为真实dom并挂载到页面上。 -
创建Watcher实例对象
创建时,传递函数updateComponents,然后调用get方法,创建完毕后,触发钩子函数mounted(),挂载结束,返回vue实例。 -
Watcher.get()
创建完watcher,会调用一次get,在get方法中会调用updateComponent(),updateComponent会调用实例化时传入的render()或者是编译模板以后生成的render(),返回vnode。然后调用vm._update(),调用vm.__patch__方法,将虚拟dom转化为真实dom并挂载到页面上,将生成的真实dom记录到vm.$el()中。
请简述 Vue 响应式原理。
Vue的data中成员实现响应式数据是在创建vue实例时,将传入构造函数的data存放在实例的data中,然后遍历data的成员,利用Object.defineProperty把它们转换成getter/setter并定义在vue实例上。然后调用observer实现data数据劫持。observer对每个成员通过Object.defineProperty将该成员转化为getter/setter并定义在该成员上,真正的响应式就发生在这里。又因为Vue使用的是观察者模式,因此在data的成员的getter中会收集该成员的所有观察者(收集依赖),在setter中发发送通知以触发观察者的update方法。经过以上对传入vue构造函数的data的加工,就实现了对data成员变成了响应式数据。
请简述虚拟 DOM 中 Key 的作用和好处。
key的作用
追踪列表中哪些元素被添加、被修改、被移除的辅助标志。可以帮助我们快速对比两个虚拟dom对象,找到虚拟dom对象被修改的元素,然后仅仅替换掉被修改的元素,再生成新的真实dom。
key的好处
可以减少dom的操作,减少diff和渲染所需要的时间,提升了性能。
请简述 Vue 中模板编译的过程。
Vue的编译功能主要是将template字符串模板编译生成render函数,render函数的功能是用js创建Dom。
-
先调用compileToFunctions(template,options,this)函数,从缓存中加载编译好的render函数,如果缓存中没有的话,调用compile(template,options)函数。
-
compile(template,options)中首先合并options,然后调用baseCompile(template.trim(), finalOptions)。
-
调用 baseCompile 函数,完成模板编译核心的三件事情。
-
通过解析器(parse)将模板字符串的模板编译转换成 AST 抽象语法树
-
优化器(optimize) - 对 AST 进行静态节点标记,主要用来做虚拟DOM的渲染优化。检测到静态子树,设置为静态,不需要在每次重新渲染的时候重新生成节点。patch阶段会跳过静态子树。
-
通过generate将AST抽象语法树转换为render函数的js字符串
-
将render函数通过createFunction函数转换为一个可以执行的函数
-
将最后的render函数挂载到Vue实例的options对应的属性中