markRaw用于在对象进入响应式系统前标记其不被代理,必须先markRaw再传入reactive或ref;若已响应式则markRaw无效;适用于第三方实例、只读配置、大型静态数据等场景。

直接用 markRaw 包裹对象,再传给 reactive 或赋值给响应式对象的属性,它就不会被 Vue 的响应式系统劫持。
必须在进入响应式系统前标记
markRaw 的作用是“提前声明:这个对象别动”。一旦对象已经被 reactive 或 ref 处理过,再调用 markRaw 就无效了。
- ✅ 正确写法:先 markRaw,再放进 reactive
const echartsInstance = markRaw(new ECharts(dom))
const state = reactive({
chart: echartsInstance // ✅ 安全,不会被代理
})
- ❌ 错误写法:先放进 reactive,再 markRaw
markRaw(badState.chart) // ❌ 已经被代理过了,无效
和 ref 搭配使用的注意点
如果用 ref 存储 markRaw 过的对象,访问时仍要通过 .value,但它的值本身是普通对象,不带响应式能力。
- ref(markRaw(obj)) 的 .value 是原始对象,可直接调用方法(比如 chart.value.setOption())
- 重新赋值 ref.value = newObj 会触发 ref 的更新,但新值也得自己 markRaw 才能跳过响应式
典型适用场景
不是所有对象都需要响应式。以下情况建议 markRaw:
- 第三方库实例(ECharts、Mapbox、Monaco Editor 等)
- 不可变数据结构(如从后端返回的只读配置对象)
- 大型静态列表项(避免为成百上千个对象创建 proxy,节省内存和初始化开销)
和 toRaw 的区别别搞混
markRaw 是“防进入”,toRaw 是“已进入后脱出”:
- markRaw(obj) → obj 永远不会变成响应式(适合初始化阶段)
- toRaw(reactiveObj) → 把已经响应式的对象转回原始对象(适合临时绕过响应式追踪)


















