markRaw的作用是预先标记对象跳过Vue响应式处理,适用于第三方实例、静态配置、超大结构数据等无需响应式的场景,必须在进入reactive前调用,不可用于已响应式对象。

markRaw 的作用很直接:告诉 Vue “这个对象别管,不用转成响应式”。它不是用来“取消”已有的响应式,而是提前打个标记,让 Vue 在后续创建响应式状态时主动跳过它。
什么时候该用 markRaw?
核心判断标准就一个:这个对象你确定它永远不会变,或者变了也不需要更新视图。
- 第三方库的实例,比如 new ECharts(dom)、new Map()、axios.create()
- 静态配置或常量,比如 { API_URL: '/api' }、['Draft', 'Published']
- 超大结构的数据,比如上万节点的树形数据、地理坐标集、离线字典表
- DOM 元素、组件实例、函数等本就不该被响应式系统处理的对象
怎么写?基本用法很简单
直接把目标对象传给 markRaw(),它会原样返回,并打上 __v_skip: true 标记:
import { markRaw, reactive } from 'vue'
// 标记一个不可变配置
const STATUS_MAP = markRaw({
1: '待审核',
2: '已通过',
3: '已拒绝'
});
// 即使放进 reactive,也不会被代理
const state = reactive({
statusOptions: STATUS_MAP,
user: { name: '张三' }
});
console.log(state.statusOptions === STATUS_MAP); // true
state.statusOptions[4] = '已撤回'; // 不触发更新,也不该这么做
和 toRaw 完全不是一回事
markRaw 是事前声明,像贴一张“勿扰”标签;toRaw 是事后解包,像拆开一个已经包好的礼物。两者目的不同、时机不同、不能互相替代。
立即学习“前端免费学习笔记(深入)”;
- 你不能对普通对象(非 reactive/ref 创建的)调用 toRaw —— 它会直接返回原对象,没意义
- 你也不能用 markRaw 去“修复”一个已经被 reactive 包裹过的对象 —— 标记必须在进 reactive 之前做
- 常见误区:以为 markRaw 能让已有响应式对象“变回普通对象”,其实不能
性能提升真的明显吗?
是的,尤其对大型数据。Vue 在构建响应式时会对对象递归遍历并建立 Proxy。markRaw 后,整个子树都被跳过。
比如渲染一棵 5000 节点的树:
- 不加 markRaw:Vue 遍历全部节点建代理,耗时可能 184ms
- 加了 markRaw:只代理根 state 对象本身,树数据完全跳过,耗时降到约 17ms










