Vue 的首次渲染的过程

本文详细介绍了Vue 2.6.10版本的初始化过程,包括构造函数中的_init方法、$mount()方法的双重作用,以及在mountComponent()中的关键步骤。重点讲解了如何从模板生成render函数,虚拟DOM的创建与更新,以及Watcher对象的创建。文章深入剖析了Vue实例从初始化到挂载到页面上的完整生命周期。

Vue版本:2.6.10

  1. 首先进行Vue的初始化,初始化Vue的实例成员和静态成员
  2. 调用构造函数中的_init()方法,作为整个Vue的入口
  3. 在_init()中调用$mount()方法:
    • 第一个$mount():在入口文件entry-runtime-with-compiler.js中。其核心作用是将模板(按照传入render>template>el的优先级作为模板)用compileToFunction()编译成render函数并存储在option.render中
    • 第二个$mount():在runtime/index.js中。运行时版本不会走第一个mount(),所以仅会在这里中获取el
  4. 调用mountComponent(),src/core/instance/lifecycle.js中定义
    1. 判断render选项,若运行时版本&没有render&传入了模板,会警告运行时版本不支持编译器
    2. 触发beforeMount()
    3. 定义updateComponent(),该方法中调用了两个方法:
      • _rende():调用了render.call(vm._renderProxy,vm$createElement)将用户传入的render()或者自己编译生成的render()生成的虚拟DOM返回
      • _update():调用了__patch__(vm.$el,vnode)将虚拟DOM转换成真实DOM,并且挂载到页面上;将生成的真实DOM记录到vm.$el中。
    4. 创建Watcher对象。创建时传递了updateComponent()并在内部调用get()时调用了updateComponent()
    5. 触发mounted()
    6. return vm
### Vue 渲染机制概述 Vue渲染机制基于虚拟 DOM 技术,通过高效的比较算法来最小化真实 DOM 的操作次数,从而提升性能。以下是关于 Vue 渲染过程的具体分析: --- #### 1. **解析模板** Vue 首先会对模板进行编译处理。这一阶段的主要工作是将 HTML 模板转换成抽象语法树(Abstract Syntax Tree, AST),以便后续生成可执行的 JavaScript 函数。 - 这一过程中,Vue 使用其内置的编译器对模板字符串进行词法分析和语法分析,最终得到一棵描述模板结构的 AST[^1]。 ```javascript // 假设有一个简单的模板 <template> <div>{{ message }}</div> </template> // 编译后的 AST 结构可能如下所示 { type: 'root', children: [ { type: 'element', tag: 'div', props: [], children: [ { type: 'interpolation', content: '{{ message }}' } ] } ] } ``` --- #### 2. **生成渲染函数** 在完成模板到 AST 的转化之后,Vue 将进一步把 AST 转换成一个可以生成虚拟 DOM 树的渲染函数 `render`。这个函数会在每次组件状态变化时被执行,返回新的虚拟 DOM 树。 - 渲染函数的核心作用是以声明式的方式定义视图逻辑,并将其转化为程序化的形式供运行时使用[^1]。 ```javascript function render() { return h('div', {}, this.message); } // 上述代码中的 `h` 是创建虚拟节点的方法 (hyperscript),类似于 React 中的 JSX ``` --- #### 3. **执行渲染函数并构建虚拟 DOM** 每当组件的状态发生改变时,Vue 会调用对应的渲染函数重新生成一颗全新的虚拟 DOM 树。这一步骤的关键在于利用 JavaScript 对象表示 DOM 结构,而不是直接操作真实的 DOM 元素。 - 此外,在首次挂载组件实例时也会触发一次完整的渲染流程,此时生成的是初始的虚拟 DOM 树[^1]。 --- #### 4. **对比新旧虚拟 DOM 树** 为了减少不必要的重绘或回流开销,Vue 实现了一套高效的 diff 算法用来比较前后两次渲染产生的两棵虚拟 DOM 树之间的差异。 - Diff 算法遵循三个主要原则:同层比较、唯一 key 属性优化以及跨级移动检测限制等策略^。 ```javascript // 差异计算伪代码示意 function patch(oldVnode, newVnode) { if (!oldVnode || !newVnode) { // 如果任一方不存在,则直接替换整个子树 replaceNode(); } else if (sameNodeType(oldVnode, newVnode)) { // 同一层节点类型相同的情况下做属性更新与子节点递归diff updateProperties(); reconcileChildren(); } else { // 类型不同则销毁老节点并新增新节点 destroyOldNodeAndCreateNewOne(); } } ``` --- #### 5. **更新真实 DOM** 最后一步就是依据上一步得出的变化集去修改实际页面上的 DOM 元素。由于之前已经尽可能缩小了改动范围,因此这里涉及的操作量通常较小,极大提升了整体效率。 - 只有那些真正发生变化的地方才会被触达至浏览器层面的真实 DOM 更新动作中去[^1]. --- ### 总结 综上所述,Vue渲染机制大致分为以下几个重要环节:从模板解析开始经过多次中间形态变换直至最终落实于屏幕显示之上;期间借助虚拟 DOM 提高了交互响应速度同时也降低了维护成本。 --- 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值