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!" // 自动触发视图更新
相关推荐
漂流瓶jz38 分钟前
快速定位源码问题:SourceMap的生成/使用/文件格式与历史
前端·javascript·前端工程化
samroom39 分钟前
iframe实战:跨域通信与安全隔离
前端·安全
fury_1231 小时前
vue3:数组的.includes方法怎么使用
前端·javascript·vue.js
weixin_405023371 小时前
包资源管理器NPM 使用
前端·npm·node.js
宁&沉沦1 小时前
Cursor 科技感的登录页面提示词
前端·javascript·vue.js
Dragonir1 小时前
React+Three.js 实现 Apple 2025 热成像 logo
前端·javascript·html·three.js·页面特效
peachSoda72 小时前
封装一个不同跳转方式的通用方法(跳转外部链接,跳转其他小程序,跳转半屏小程序)
前端·javascript·微信小程序·小程序
@PHARAOH3 小时前
HOW - 浏览器兼容(含 Safari)
前端·safari
undefined在掘金390413 小时前
flutter 仿商场_首页
前端