你应该知道的Vue小知识

155 阅读4分钟

请简述 Vue 首次渲染的过程。

  1. Vue初始化,实例成员、静态成员
    首先进行vue的初始化,即初始化实例成员及静态成员。

  2. new Vue()
    初始化结束以后,调用vue的构造函数new Vue(),在构造函数中调用this._init()方法。

  3. this.init()
    this.init()相当于整个项目的入口,在这个方法中,最终调用vm.$mount()。

  4. vm.$mount()
    这个mount()是src/platform/web/entry-runtime-with-compiler.js中定义的,核心作用是把模板编译为render函数,判断是否有render选项,如果没有,则会获取template选项,如果template也没有,会把el中的内容作为模板,通过compileToFunctions()方法将模板编译为render函数,编译好以后,将render存入到options.render中。

  5. **vm.mount()调用src/platforms/web/runtime/index.js文件中的mount方法,这个方法中会重新获取el,因为如果是运行时版本的话,是不会走entryruntimewithcompiler.js这个入口中获取el,所以如果是运行时版本的话,我们会在runtime/index.jsmount()** 调用src/platforms/web/runtime/index.js文件中的mount方法,这个方法中会重新获取el,因为如果是运行时版本的话,是不会走entry-runtime-with-compiler.js这个入口中获取el,所以如果是运行时版本的话,我们会在runtime/index.js的mount()中重新获取el。

  6. mountComponent(this,el)
    这个方法在src/core/instance/lifecycle.js中定义的,首先判断是否有render选项,如果没有但是传入了模板,并且当前是开发环境,则发出警告(运行时版本不支持编译器),触发beforeMount钩子函数(开始挂载之前),定义updateComponents函数但是并未调用,这个函数中调用render()和update()两个方法,render是生成虚拟dom,update是将虚拟dom转化为真实dom并挂载到页面上。

  7. 创建Watcher实例对象
    创建时,传递函数updateComponents,然后调用get方法,创建完毕后,触发钩子函数mounted(),挂载结束,返回vue实例。

  8. 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。

  1. 先调用compileToFunctions(template,options,this)函数,从缓存中加载编译好的render函数,如果缓存中没有的话,调用compile(template,options)函数。

  2. compile(template,options)中首先合并options,然后调用baseCompile(template.trim(), finalOptions)。

  3. 调用 baseCompile 函数,完成模板编译核心的三件事情。

  4. 通过解析器(parse)将模板字符串的模板编译转换成 AST 抽象语法树

  5. 优化器(optimize) - 对 AST 进行静态节点标记,主要用来做虚拟DOM的渲染优化。检测到静态子树,设置为静态,不需要在每次重新渲染的时候重新生成节点。patch阶段会跳过静态子树。

  6. 通过generate将AST抽象语法树转换为render函数的js字符串

  7. 将render函数通过createFunction函数转换为一个可以执行的函数

  8. 将最后的render函数挂载到Vue实例的options对应的属性中