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 看组件树,对比一下两者的映射关系------以后碰到性能问题,你脑海里就会浮现这两棵树的对比图!😄

相关推荐
谙忆10241 小时前
图像任务超时怎么重试:先分执行状态,再做结果验收
javascript
@大迁世界9 小时前
Firefox 本地模式:localhost 再见了 ?
前端·架构
米米商聊11 小时前
同名附件为什么被 Map 覆盖?重复键与一对多索引
前端·javascript
echome88812 小时前
Python 异常处理:try、else、finally 的正确搭配
开发语言·前端·python·异常处理·编程技巧
时间的情敌12 小时前
OpenLayers 实战|Vue3 + OpenLayers 完整工程案例(加载天地图、要素、弹窗、绘制、WFS)
前端·openlayers
陈随易12 小时前
下载神器!Motrix 停更三年后重写回归
前端·后端·程序员
前端的日常13 小时前
一个人+AI做情侣食谱小程序,0 费用的服务器
前端·后端
计算机魔术师13 小时前
谷歌搜索广告踩刹车,AI广告成为救命稻草
前端
总要学点什么13 小时前
第81篇:数据可视化-PM2.5分布——让圆点的胖瘦替每座城市报出浓度
前端·信息可视化·echarts·cesium·空间分析
IT_陈寒13 小时前
Vue的v-for里用了个临时变量,页面直接挂了
前端·人工智能·后端