DOM、BOM、DOM操作详解 + 结合Vue响应式关联梳理
一、基础概念区分
1. BOM(Browser Object Model 浏览器对象模型)
定义 :浏览器提供的、用来操作浏览器窗口本身 的API,核心宿主是window,脱离HTML文档,只管浏览器窗口。
- 核心对象:
window(顶级对象) - 常用成员:
- 窗口控制:
window.open/close/resize - 地址:
location(跳转、获取地址、刷新) - 历史记录:
history(前进、后退、history路由) - 设备信息:
navigator(浏览器、系统) - 弹窗、定时器:
alert/setTimeout/setInterval
- 窗口控制:
- 特点:和页面DOM节点无关,只操控浏览器外壳。
2. DOM(Document Object Model 文档对象模型)
定义 :浏览器把HTML文档解析为树形JS对象,把标签、文本、属性抽象成节点树,提供API用来操作页面标签内容。
- 根对象:
document,隶属于window; - 结构:DOM树 = 根节点→元素节点、文本节点、属性节点、注释节点;
- 核心作用:页面结构、内容、样式的增删改查。
3. DOM操作
所有通过DOMAPI修改页面节点的行为,统称为DOM操作,分为4大类:
- 查询 :
getElementById、querySelector、children、parentNode - 增删 :
createElement、appendChild、removeChild - 修改内容 :
innerText、innerHTML、textContent - 修改属性样式 :
setAttribute、classList、style
原生DOM痛点
频繁DOM操作会重排(回流)、重绘 ,浏览器渲染开销大,页面卡顿; 原生JS开发需要手动频繁操作DOM,Vue/React核心目的就是减少手动DOM操作。
二、DOM、BOM、DOM操作 简单对比总结
| 类别 | 管控范围 | 顶级对象 | 典型用途 |
|---|---|---|---|
| BOM | 浏览器窗口 | window | 页面跳转、定时器、路由历史 |
| DOM | HTML页面文档 | document | 标签增删改查、页面渲染 |
| DOM操作 | 调用DOMAPI | document | 手动修改页面视图 |
三、Vue响应式中,DOM/BOM/DOM操作的关联与运用
Vue响应式的最终目的:数据驱动视图,本质就是:数据变化 → 自动执行DOM操作更新页面,不再手动写DOM代码。
1. 响应式闭环最终落地:DOM操作
- 初始化 data做响应式劫持 → 执行渲染函数(render) render函数内部会调用虚拟DOM,转换成真实DOM,挂载到页面(DOM插入操作)。
- 依赖收集 读取数据触发get,收集渲染副作用函数,这个函数本质就是生成DOM、更新DOM的逻辑。
- 数据更新 修改数据触发set/Proxy拦截 → 触发trigger/notify → 执行渲染函数 → 对比新旧VNode → 打补丁
patch→ 执行批量DOM操作修改页面。
核心结论:响应式只是数据监听手段,视图更新的最后一步一定是DOM操作,Vue只是封装、自动化了DOM操作。
2. Vue中关键DOM相关机制
(1)虚拟DOM(VNode)
原生频繁DOM操作性能差,Vue用JS对象描述DOM结构(虚拟DOM):
- 数据更新后,先生成新VNode,和旧VNode做diff对比;
- 只找出差异节点,最小化DOM修改,减少回流重绘;
- diff算法的输出结果,就是精准的DOM增删改指令。
(2)patch 补丁函数
diff对比完成后,patch专门执行真实DOM操作: 新增节点→appendChild、删除节点→removeChild、修改内容→innerHTML、移动节点等。
(3)模板编译
.vue模板编译为render函数,render函数返回VNode,是DOM的JS描述体。
(4)异步更新&nextTick
- 短时间多次修改数据,不会立刻执行DOM操作,Vue存入异步队列防抖;
- 等同步代码执行完毕,统一执行一次patch批量DOM渲染;
$nextTick:DOM更新完成后执行回调,用来获取最新DOM节点,是DOM操作常用API。
3. BOM在Vue中的使用场景(和响应式无直接绑定,但高频搭配)
- 路由:
history、location实现hash/history路由; - 定时器:
setTimeout搭配防抖节流监听数据; - 窗口监听:
window.resize结合响应式数据做自适应; BOM属于浏览器环境API,不属于响应式核心流程,只是业务常用工具。
4. 响应式体系里,哪些环节直接接触DOM操作
- 首次挂载mount:新建DOM、插入DOM;
- 更新渲染patch:diff后增删改DOM;
- 指令 :v-show、v-if、v-bind、v-text内部都是DOM操作;
- v-if:创建/销毁DOM
- v-show:修改display样式
- v-text:修改元素文本
- ref:直接获取DOM元素,用于手动DOM操作;
- 生命周期:
mounted:DOM已挂载,可操作DOM;updated:DOM更新完毕。
5. 为什么响应式能省去手动DOM操作?
- 开发者只修改JS数据;
- 响应式监听数据变化;
- 框架自动执行render→diff→patch;
- 框架自动完成DOM增删改; 全程不需要开发者手写
appendChild、querySelector等原生代码。
四、补充易错点
- 响应式 ≠ DOM操作:响应式管数据监听 ,DOM操作管视图修改,前者是前提,后者是结果;
- Vue不能完全脱离DOM:框架只是封装,底层视图更新依旧依赖DOMAPI;
- Vue2 Object.defineProperty、Vue3 Proxy只做数据劫持,本身不操作DOM,只是通知渲染函数去更新DOM。