vue3-DOM树

DOM 树是浏览器理解并呈现网页的"骨架" 。无论你用的是 Vue、React 还是原生 JS,所有前端框架最终都在操作这棵树。

结合你的学习进度(Vue3 虚拟 DOM、构建工具),我带你彻底搞懂这棵"树"的物理结构 、生成过程 ,以及Vue 为什么要搞一个"虚拟 DOM"来模拟它。


1. 什么是 DOM 树?(纸上建筑模型)

当浏览器(如 Chrome)加载你的 index.html 时,它做的第一件事不是画图,而是**"读代码,搭积木"**。

定义 :DOM(文档对象模型,Document Object Model)树是一个内存中的多叉树结构 ,它用节点(Node) 的形式完整地表达了 HTML 文档的层级关系。

类比 :想象一栋房子的建筑结构图。

  • 根节点(document):就是这块地皮。
  • <html>:房屋的主体框架。
  • <head> 和 <body>:房子的水电管道和居住空间。
  • <div>、<p>、<button>:房间里的墙壁、家具和开关。

代码映射:

复制代码
<!DOCTYPE html>
<html>
  <head>
    <title>我的页面</title>
  </head>
  <body>
    <div id="app">
      <h1>标题</h1>
      <p>段落</p>
    </div>
  </body>
</html>

对应的 DOM 树逻辑结构:

复制代码
document
 └── html
      ├── head
      │    └── title
      │         └── "我的页面"
      └── body
           └── div#app
                ├── h1
                │    └── "标题"
                └── p
                     └── "段落"

2. 这棵树由哪些"积木"(节点)组成?

DOM 树由 不同类型的节点(Node) 构成,你在 Vue 模板中写的标签,最终都会变成以下 3 种主要节点:

节点类型 例子 描述
元素节点(Element) <div>, <p>, <button> 构成网页结构的骨架,可以嵌套子节点。
文本节点(Text) "标题", "段落" 叶子节点,没有子级,存放真正的文字内容。
属性节点(Attribute) id="app", class="box" 挂在元素节点上,不属于树的主干(通常不单独算作树的层级)。

3. 浏览器是如何"造"出这棵树的?(关键流程)

当你输入网址并回车,浏览器的渲染引擎(如 Chrome 的 Blink)会经历:

  1. 词法分析(Tokens):将 HTML 字符串拆解成开始标签、结束标签、属性、文本。
  2. 构建节点(Nodes):根据标签创建对应的 JS 对象。
  3. 建立父子关系 :遇到 <div> 就作为当前父节点的最后一个儿子插入,形成 深度优先(DFS) 的树结构。
  4. 触发关键渲染路径 :DOM 树构建完成后,会与 CSSOM 树(样式树) 合并成 Render Tree(渲染树),最终绘制成屏幕上的像素。

4. 致命的痛点:为什么直接操作 DOM 树很"昂贵"?

在原生 JS 中,你写 document.getElementById('app').innerHTML = 'xxx',就是直接修改这棵树。

痛点:

  • 回流(Reflow) :当你改了 width 或 display,浏览器不仅要改这棵树,还要重新计算所有子元素的几何位置(就像你抽走了积木底层的方块,整座塔都要垮塌重建)。
  • 重绘(Repaint) :即使只改了 color 这种不改变布局的属性,浏览器也得重新把像素画一遍。

结论:每秒操作 60 次 DOM 树,很容易造成页面卡顿(掉帧)。


5. Vue 3 的救命稻草:虚拟 DOM(Virtual DOM)与 Diff 算法

既然操作真树这么贵,Vue 就在 JS 内存里造了一棵**"假树(虚拟 DOM)"**。

运作流程:

  1. 造梦 :你写了 <template>,Vue 编译成 render 函数,生成一个轻量的 JS 对象(虚拟 DOM 树)。
  2. 挂载:Vue 拿着这棵虚拟树,一次性创建真实的 DOM 树。
  3. 变化 :数据变了(比如 message.value 变了),Vue 生成新的虚拟树。
  4. 对比(Diff) :Vue 拿出 "新树" 和 "老树" 对比,找出具体是哪个节点、哪个属性变了(这个算法叫 Patch)。
  5. 打补丁 :Vue 只去修改那一个真实的 DOM 节点,其他几百个没变的节点原封不动。

这就是你之前学的 v-for 必须加 :key 的底层原理 ::key 是给虚拟 DOM 树上的节点打上的"身份证号",让 Diff 算法能精确判断是"移动了位置"还是"完全新建",从而极大提升 DOM 树的复用效率!


6. 结合你的代码看,DOM 树在哪里?

在你的 Vue 父组件中:

复制代码
<template>
  <div class="parent-component">   <!-- 1. 真实 DOM 树的起点 -->
    <h3>👨‍👦 父组件</h3>           <!-- 2. 文本节点 -->
    <ChildComponent />             <!-- 3. 这是 Vue 的"组件节点",在 DOM 树上会被替换为组件内部的真实元素 -->
  </div>
</template>
  • 最终在浏览器控制台(F12 -> Elements)中看到的,全是真实的 DOM 树节点。
  • 而你的 ChildComponent 在编译阶段,会被 Vue 打平或插入,最终成为真实 DOM 树上的一个 <div> 子树。

7. Windows 11 开发者工具中的上帝视角

想亲眼看这棵树长什么样?在 Chrome/Edge 中:

  1. 按 F12 打开开发者工具。
  2. 点击 Elements(元素) 标签。
  3. 你看到的那个可折叠、缩进的层级结构 ,就是当前页面在内存中的 真实 DOM 树!
  4. 如果你开了 Vue Devtools,你看到的是一棵虚拟组件树,它更清晰,但不完全等于 DOM 树。

总结一句话记忆

DOM 树是浏览器内存中一颗由 HTML 标签构成的"家族谱系树",操作它非常消耗性能;而 Vue 在 JS 里造了一颗"模拟树(虚拟 DOM)",通过 Diff 算法精准只修改真实树上的必要部分,这就是 Vue 性能优化的核心密码。

现在打开你正在运行的项目,按 F12 看 Elements,再打开 Vue Devtools 看组件树,对比一下两者的映射关系------以后碰到性能问题,你脑海里就会浮现这两棵树的对比图!😄

相关推荐
anxiao_m1 分钟前
水利数字孪生怎么选?主流可视化渲染平台深度横向测评
大数据·前端·人工智能·图形渲染·云渲染
kill52210 分钟前
useRef
前端·javascript·react.js
蓝悦无人机12 分钟前
从“摸形状“到“点到线面的距离“——聊聊 SLAM 前端(激光雷达篇)
前端·loam·数据关联·激光slam·点云特征提取·点到线面距离·icp/ndt
米多科技26 分钟前
我做了一个 3D 虚拟世界基底,在上面再搭 3D 世界或元宇宙,事半功倍
javascript·人工智能·github
flash俊杰43 分钟前
工程约束怎么不拖后腿
前端
霍营_托尼1 小时前
纯前端播 40GB 本地视频?我把浏览器改造成了「磁盘流式」播放器
前端·javascript·音视频开发
溪语流沙1 小时前
【Web全栈进阶】FastAPI工程化:APIRouter拆分 + 配置 + 依赖注入
java·前端·fastapi
Shirley~~1 小时前
Three.js的基础概念
前端·3d
deli0071 小时前
黏菌没有大脑,3000 个 Physarum 粒子跑 12973 步自己铺出了迷宫最短路
前端
凌云若寒1 小时前
BarTender提示#807错误:无法在拥有其他许可证的Licensing Service上激活节点锁定的 Professional 版许可证 的解决办法
运维·服务器·前端·学习·软件需求