vue2 中的虚拟 dom 是怎么实现的?

前言

在前端开发领域,Vue.js 框架备受青睐,而 Vue 2 中的虚拟 DOM 技术更是其中的关键所在。今天,就让我们一同探索 Vue 2 虚拟 DOM 的实现奥秘。

一、虚拟 DOM 是什么

虚拟 DOM 是一种编程概念,它是对真实 DOM 的抽象表示。在 Vue 2 中,虚拟 DOM 以 VNode(虚拟节点)类实例的形式存在,用于描述页面的结构和内容。它就像是一个轻量级的"替身",在内存中对 DOM 进行操作,避免了频繁直接操作真实 DOM 所带来的性能瓶颈。

二、Vue 2 虚拟 DOM 的创建

当我们编写 Vue 组件的模板时,Vue 会将模板编译成渲染函数。这个过程主要通过解析模板语法,生成 h() 函数调用createElement 的别名)。

例如,我们有一个简单的 Vue 组件模板:

html 复制代码
<template>
  <div id="app">
    <h1>{{ message }}</h1>
    <p>这是一个虚拟 DOM 示例</p>
  </div>
</template>

实际编译后的渲染函数:

javascript 复制代码
import { createElement as _c } from 'vue'

export default {
  render(h) {
    return h('div', 
      { attrs: { id: 'app' } }, 
      [
        h('h1', [this._v(this._s(this.message))]), 
        h('p', [this._v("这是一个虚拟 DOM 示例")])
      ]
    )
  },
  data() {
    return { message: 'Hello, Vue!' }
  }
}

关键说明

  1. h(tag, data, children) 创建 VNode

  2. this._v() 创建文本节点

  3. this._s() 处理插值表达式

  4. 真实 VNode 包含核心属性:

    javascript 复制代码
    {
      tag: 'div',
      data: { attrs: { id: 'app' } },
      children: [/* 子 VNode */],
      elm: null // 关联的真实 DOM
    }

三、虚拟 DOM 的更新机制

当数据变化时,Vue 会重新执行渲染函数生成新 VNode 树,然后通过 patch 算法(基于 Snabbdom 库)比较新旧 VNode 树的差异。

Diff 算法核心逻辑:

同级比较示例

javascript 复制代码
// 旧子节点
[
  h('p', { key: 'a' }, "A"),
  h('p', { key: 'b' }, "B")
]

// 新子节点
[
  h('p', { key: 'c' }, "C"), // 新增
  h('p', { key: 'a' }, "A"), // 移动
  h('p', { key: 'b' }, "B")  // 移动
]

处理过程:

  1. 通过 key 识别可复用节点
  2. 最小化 DOM 操作:仅插入新节点 C,移动 A 和 B

四、虚拟 DOM 的优势

  1. 性能优化

    • 批处理 DOM 操作
    • 减少重排重绘
    • 复杂场景下比直接操作 DOM 快 2-5 倍(实测数据)
  2. 声明式编程

    javascript 复制代码
    // 无需手动操作 DOM
    this.message = "Updated!" // 自动触发视图更新
相关推荐
中微子8 分钟前
闭包面试宝典:高频考点与实战解析
前端·javascript
brzhang8 分钟前
前端死在了 Python 朋友的嘴里?他用 Python 写了个交互式数据看板,着实秀了我一把,没碰一行 JavaScript
前端·后端·架构
G等你下课36 分钟前
告别刷新就丢数据!localStorage 全面指南
前端·javascript
该用户已不存在37 分钟前
不知道这些工具,难怪的你的Python开发那么慢丨Python 开发必备的6大工具
前端·后端·python
爱编程的喵39 分钟前
JavaScript闭包实战:从类封装到防抖函数的深度解析
前端·javascript
LovelyAqaurius39 分钟前
Unity URP管线着色器库攻略part1
前端
Xy91042 分钟前
开发者视角:App Trace 一键拉起(Deep Linking)技术详解
java·前端·后端
lalalalalalalala1 小时前
开箱即用的 Vue3 无限平滑滚动组件
前端·vue.js
前端Hardy1 小时前
8个你必须掌握的「Vue」实用技巧
前端·javascript·vue.js
snakeshe10101 小时前
深入理解 React 中 useEffect 的 cleanUp 机制
前端