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!" // 自动触发视图更新
相关推荐
知了清语3 分钟前
pnpm之monorepo项目, vite版本冲突, 导致vite.config.ts ts警告处理
前端
弗锐土豆26 分钟前
一个基于若依(ruoyi-vue3)的小项目部署记录
前端·vue.js·部署·springcloud·ruoyi·若依
Hilaku29 分钟前
我为什么放弃了“大厂梦”,去了一家“小公司”?
前端·javascript·面试
1undefined230 分钟前
element中的table改造成虚拟列表(不定高),并封装成hooks
前端·vue.js
浅墨momo34 分钟前
搭建第一个Shopify App
前端·程序员
然我39 分钟前
React 事件机制:从代码到原理,彻底搞懂合成事件的核心逻辑
前端·react.js·面试
Codebee39 分钟前
OneCode 组件服务通用协议栈:构建企业级低代码平台的技术基石
前端·前端框架·开源
Running_C39 分钟前
常见web攻击类型
前端·http
jackyChan39 分钟前
ES6 Proxy 性能问题,你真知道吗?🚨
前端·javascript