markRaw用于标记对象彻底跳过Vue响应式系统,不创建Proxy、不递归处理、不收集依赖;适用于静态配置、第三方实例、超大树形数据、DOM/组件引用等只读且无需视图更新的场景。

直接用 markRaw 包裹不需要响应式追踪的对象,就能让 Vue 在初始化代理阶段彻底跳过它——不创建 Proxy,不递归处理嵌套属性,也不收集依赖。这对渲染性能提升非常直观,尤其在处理大型结构化数据时。
哪些数据适合 markRaw
核心判断标准:该对象在组件生命周期内不会被修改,且它的变化无需触发视图更新。
- 静态配置类对象:如 API 地址、主题色、枚举映射表等只读数据
- 第三方库实例:ECharts 实例、Map 容器、Canvas 上下文、Axios 实例等自带状态和方法的对象
- 超大树形或列表原始数据:后端返回的完整组织架构、文件目录树、长表格原始 JSON,字段多、层级深、确定不变
-
DOM 元素或组件实例引用:通过
ref拿到的或子组件 proxy,本身不需要响应式追踪
怎么用才真正生效
必须在对象进入响应式系统前标记,不是“事后补标”。常见错误是先赋值给 ref 或 reactive,再试图用 markRaw 补救——这已经晚了。
Element Plus Vue3 桌面组件库。在开发 Vue 3.x 页面时调用,使用 Element Plus 组件(如 el-button、el-input、el-form、el-table 等)。
- 正确写法:
const treeData = ref(markRaw(res))或const state = reactive({ config: markRaw(staticConfig) }) - 错误写法:
const data = ref({}); data.value = markRaw(res)—— 此时data已被代理,markRaw失效 - 注意:
markRaw返回原对象本身,不新建副本,仅添加不可枚举的__v_skip标记
性能对比很真实
实测中,一个含 2000+ 节点、平均深度 5 层的树结构,不做处理直接进 ref,首次渲染耗时约 184ms;仅做字段精简可降到 82ms;加上 markRaw 后直接压到 17ms——因为 Vue 连第一层属性都没去 Proxy,更不会递归 traverse 子节点。
- 它不是“浅响应式”,而是“零响应式”:连顶层访问都不触发依赖收集
- 配合数据清洗(只保留渲染所需字段)效果更佳
- 对后续所有操作免疫:放进
reactive、赋给ref.value、作为 prop 传入子组件,都不会被转为响应式
别和 toRaw 混了
markRaw 是源头拦截,toRaw 是事后还原。前者防止代理发生,后者把已有的代理对象“剥掉壳”。如果你需要把响应式对象传给 Lodash 或导出为 JSON,用 toRaw;如果你明确知道某个对象从诞生起就不该进响应式系统,就用 markRaw。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









