markraw的作用是预先标记对象跳过vue响应式处理,适用于第三方库实例(如echarts、three.js)、静态配置、超大结构数据等无需响应式的场景,必须在进入reactive前调用。

markRaw 的作用很明确:在数据进入响应式系统前,告诉 Vue “这个对象别代理,保持原样”。它不是事后补救,而是一张提前贴上的“免劫持”标签,特别适合保护第三方库实例不被 Proxy 干扰。
为什么第三方实例必须用 markRaw?
像 ECharts、Three.js、Leaflet、Canvas 2D 上下文这类库,内部依赖原始引用、自有状态更新机制或特殊属性(如 getter/setter、Symbol 键、原型方法)。一旦被 Vue 的 Proxy 包裹,就可能出现:
- === 判断失败(代理对象 ≠ 原始实例)
- 方法调用报错(如 chart.setOption() 内部逻辑被拦截异常)
- 视图不更新或反复重绘(Proxy 触发多余依赖收集)
- 内存泄漏(代理对象与库自身引用关系错乱)
正确写法:初始化后立刻标记
关键原则是——必须在传给 reactive 或 ref 之前调用 markRaw。常见错误是先包进 ref,再想“修复”,这已经晚了。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- ✅ 正确(ECharts 场景):const chart = markRaw(echarts.init(domRef.value))
- ✅ 正确(Three.js 场景):const scene = markRaw(new THREE.Scene())
- ✅ 正确(Canvas 场景):const ctx = markRaw(canvas.getContext('2d'))
- ❌ 错误:const chart = ref(echarts.init(domRef.value))(Vue 会自动代理,大概率出问题)
嵌套使用时要注意引用一致性
如果把 markRaw 对象放进 reactive 中,它本身不会被代理,但它的子属性仍可能被“意外代理”——除非你也对子级做了标记。
- 例如:const config = markRaw({ theme: 'dark', data: { x: 1 } }) → config 不响应式,但 config.data 仍是普通对象,若后续赋给 reactive,它会被代理
- 若需整棵树豁免,每个层级都应 markRaw,或直接用 shallowReactive 控制代理深度
- 判断是否生效:打印 console.log(isReactive(config)) 应返回 false
和 toRaw 不是一个东西,别混用
toRaw 是给已有的响应式对象“临时拆包”,用于读取或安全写入;markRaw 是源头阻断,让对象从一开始就不进响应式流水线。两者目的、时机、不可互换。
- 你不能对一个已被 reactive 包裹的图表实例调用 markRaw 来“撤销”代理
- 你也不该对刚 new 出来的 Map 或 Date 实例调用 toRaw——它根本不是响应式,toRaw 返回的就是它自己,毫无意义
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










