第四篇:readonly VS shallowReadonly

184 阅读2分钟

在 Vue 3 中,readonlyshallowReadonly 是两个用于创建只读响应式代理的实用函数。它们的主要目的是为了防止意外修改对象的属性,但它们在实现这一点上有不同的方式。

readonly

readonly 函数创建一个只读的响应式代理对象。这意味着你不能直接修改对象的属性,但如果你修改对象内部的嵌套属性,仍然会导致响应式系统的更新。

用途

  • 完全只读:当你希望整个对象及其所有嵌套属性都变为只读时。
  • 防止意外修改:当你希望确保没有人能直接修改对象时。

示例

import { reactive, readonly } from 'vue';

const state = reactive({ 
  count: 0,
  details: { name: 'Alice' }
});

const stateReadOnly = readonly(state);

// 试图修改顶层属性会失败
stateReadOnly.count = 10; // TypeError: Cannot assign to read only property 'count'

// 试图修改嵌套属性也会失败
stateReadOnly.details.name = 'Bob'; // TypeError: Cannot assign to read only property 'name'

shallowReadonly

shallowReadonly 函数创建一个只读的响应式代理对象,但只针对顶层属性。这意味着你可以修改嵌套对象的属性,而不会触发错误。

用途

  • 部分只读:当你只想保护顶层属性不被修改时。
  • 性能优化:当嵌套对象很大或包含许多嵌套层次时,使用 shallowReadonly 可以避免代理这些对象,从而提高性能。

示例

import { reactive, shallowReadonly } from 'vue';

const state = reactive({ 
  count: 0,
  details: { name: 'Alice' }
});

const stateShallowReadOnly = shallowReadonly(state);

// 试图修改顶层属性会失败
stateShallowReadOnly.count = 10; // TypeError: Cannot assign to read only property 'count'

// 但是可以修改嵌套属性
stateShallowReadOnly.details.name = 'Bob'; // 成功修改

比较

  • readonly:创建一个完全只读的响应式代理对象,包括所有的嵌套属性。
  • shallowReadonly:创建一个只读的响应式代理对象,但只对顶层属性进行只读处理,嵌套属性仍然可以修改。

何时使用

  • 当你需要保护整个对象及其所有嵌套属性时,使用 readonly
  • 当你只需要保护顶层属性,而嵌套属性可以自由修改时,使用 shallowReadonly

总结

readonlyshallowReadonly 都是为了创建只读的响应式代理对象。readonly 会保护整个对象及其所有嵌套属性,而 shallowReadonly 只保护顶层属性。根据你的具体需求选择合适的函数来保护对象或提高性能。