返回

揭秘Vue中的toRaw和markRaw:响应式与原生对象的艺术

前端

操控响应式对象:从 toRaw 到 markRaw

在 Vue 的响应式系统中,响应式对象通过 Proxy 代理对象实现,从而能够自动侦测属性变化并触发 Vue 更新。然而,有时我们需要直接访问响应式对象的原始值,或者防止普通对象被 Vue 响应式系统侦测。这就引入了两个实用的 API:toRaw()markRaw().

从响应式到原生:toRaw()

toRaw() 方法将一个响应式 Proxy 代理对象转换为普通对象。转换后的普通对象与响应式对象具有相同的值,但失去了响应式特性。这意味着对普通对象进行修改不会触发 Vue 的更新。

使用场景:

  • 将响应式对象传递给非 Vue 组件
  • 对响应式对象进行深拷贝
  • 访问响应式对象的原始值

示例代码:

const app = Vue.createApp({
  data() {
    return {
      name: 'John Doe',
      age: 30
    };
  }
});

const rawData = app.config.globalProperties.toRaw(app.data);

console.log(rawData); // { name: 'John Doe', age: 30 }

rawData.name = 'Jane Doe';

console.log(app.data.name); // 'John Doe' (响应式对象未更新)

标记为不可代理:markRaw()

markRaw() 方法与 toRaw() 相反,它将一个普通对象标记为不可 Proxy 代理的对象。这表示 Vue 不会对标记为不可代理的对象进行响应式处理。

使用场景:

  • 在 Vue 组件中使用普通对象
  • 防止某个对象被 Vue 响应式系统侦测
  • 将普通对象传递给非 Vue 组件

示例代码:

const app = Vue.createApp({
  data() {
    return {
      user: markRaw({
        name: 'John Doe',
        age: 30
      })
    };
  }
});

app.user.name = 'Jane Doe';

console.log(app.user.name); // 'Jane Doe' (未触发 Vue 更新)

总结

toRaw()markRaw() 是 Vue 提供的两个强大 API,它们允许开发者在响应式和原生对象之间灵活转换。通过使用这些方法,开发者可以轻松地处理需要直接访问原始值或防止某些对象被响应式系统侦测的情况。

常见问题解答

Q:为什么我们需要 toRaw()

A:我们需要 toRaw() 来将响应式对象转换为普通对象,以便将其传递给非 Vue 组件或进行深拷贝等操作。

Q:为什么我们需要 markRaw()

A:我们需要 markRaw() 来防止 Vue 响应式系统侦测某些普通对象,从而避免不必要的侦测和更新开销。

Q:toRaw()markRaw() 有什么区别?

A:toRaw() 将响应式对象转换为普通对象,而 markRaw() 将普通对象标记为不可代理对象。

Q:什么时候使用 toRaw()

A:当我们需要直接访问响应式对象的原始值或将其传递给非 Vue 组件时。

Q:什么时候使用 markRaw()

A:当我们需要在 Vue 组件中使用普通对象或防止 Vue 侦测某些对象时。