首页 > 编程笔记 > JavaScript笔记
阅读:107
Vue3 readonly()和shallowReadonly()函数的用法(附带实例)
Vue 中,无论是 reactive 对象(也称为代理对象)还是 ref 对象,进行的都是深度响应式处理。也就是说,我们通过 reactive 对象或 ref 对象进行属性的深度读取和修改操作,修改后能触发页面的自动更新。
如果我们想产生一个只包含读取能力的 reactive 对象,就可以使用 readonly() 与 shallowReadonly() 函数。
readonly() 和 shallowReadonly() 函数接收的参数是一样的,其可以是一个原始的非响应式对象,也可以是响应式的 reactive 对象。只是 readonly() 函数产生的 reactive 对象是深度只读的,而 shallowReadonly() 函数产生的 reactive 对象只有外层属性是只读的,所有嵌套的内部属性都是可读/写的。
下面我们以接收一个 reactive 对象为例来演示 readonly() 与 shallowReadonly() 函数的使用方法,代码如下:

图 1 代码运行后的页面效果
同时 Vue3 提供了用来判断是否是只读 reactive 对象的工具函数 isReadonly(),如果是通过 readonly() 或 shallowReadonly() 函数产生的只读对象,则 isReadonly() 函数返回 true,否则返回 false,验证如下:
如果我们想产生一个只包含读取能力的 reactive 对象,就可以使用 readonly() 与 shallowReadonly() 函数。
readonly() 和 shallowReadonly() 函数接收的参数是一样的,其可以是一个原始的非响应式对象,也可以是响应式的 reactive 对象。只是 readonly() 函数产生的 reactive 对象是深度只读的,而 shallowReadonly() 函数产生的 reactive 对象只有外层属性是只读的,所有嵌套的内部属性都是可读/写的。
下面我们以接收一个 reactive 对象为例来演示 readonly() 与 shallowReadonly() 函数的使用方法,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>readonly 与 shallowReadonly 函数</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
</head>
<body>
<div id="app">
<h3>reactive 对象显示</h3>
<p>person.name: {{person.name}}</p>
<p>person.addr.city: {{person.addr.city}}</p>
<h3>readonly 对象显示</h3>
<p>Person.name: {{rPerson.name}}</p>
<p>Person.addr.city: {{rPerson.addr.city}}</p>
<h3>shallowReadonly 对象显示</h3>
<p>srPerson.name: {{srPerson.name}}</p>
<p>srPerson.addr.city: {{srPerson.addr.city}}</p>
<button @click="update1">通过 reactive 对象更新</button>
<button @click="update2">通过 readonly 对象更新</button>
<button @click="update3">通过 shallowReadonly 对象更新</button>
</div>
<script>
const { createApp, reactive, readonly, shallowReadonly } = Vue
createApp({
setup() {
// 产生深度可读/写的 reactive 对象
const person = reactive({
name: '张三',
addr: {
city: '北京',
},
});
// 产生源度只读的 reactive 对象
const rPerson = readonly(person);
// 产生浅只读的 reactive 对象
const srPerson = shallowReadonly(person);
const update1 = () => {
person.name += '--'; // 控制台没有警告提示,页面会自动更新
person.addr.city += '+'; // 控制台没有警告提示,页面会自动更新
};
const update2 = () => {
rPerson.name += '--'; // 控制台给出警告提示,且页面不会自动更新
rPerson.addr.city += '+'; // 控制台给出警告提示,且页面不会自动更新
};
const update3 = () => {
srPerson.name += '--'; // 控制台给出警告提示,且页面不会自动更新
srPerson.addr.city += '+'; // 控制台没有警告提示,页面会自动更新
};
return {
person,
rPerson,
srPerson,
update1,
update2,
update3,
};
},
}).mount('#app');
</script>
</body>
</html>
代码运行后的页面效果如下图所示:
图 1 代码运行后的页面效果
- 当点击“通过reactive对象更新”按钮时,在回调中通过 reactive 对象更新外部属性 name 或内部属性 city,程序是正常运行的,且页面会自动更新;
- 当点击“通过readonly对象更新”按钮时,在回调中通过 readonly() 函数产生的深度只读 reactive 对象来更新外部属性 name 或内部属性 city,控制台会给出警告提示,且页面不会自动更新;
- 当点击“通过shallowReadonly对象更新”按钮时,在回调中通过 shallowReadonly() 函数产生浅只读 reactive 对象,如果更新外部属性 name,则控制台会给出警告提示,且页面不会自动更新,如果更新内部属性 city,则程序正常运行,且页面会自动更新。
同时 Vue3 提供了用来判断是否是只读 reactive 对象的工具函数 isReadonly(),如果是通过 readonly() 或 shallowReadonly() 函数产生的只读对象,则 isReadonly() 函数返回 true,否则返回 false,验证如下:
console.log(isReadonly(person)); // false console.log(isReadonly(rPerson)); // true console.log(isReadonly(srPerson)); // true那么 readonly() 与 shallowReadonly() 函数进行只读对象转化操作的应用场景是什么呢?试想,如果在项目开发过程中团队成员开发了一些功能组件,想要实现其他成员可以使用对应组件,但不能修改其数据,也就是对功能进行一定的约束,就可以通过 readonly() 与 shallowReadonly() 函数将数据进行只读转化,这样既可以保证程序的高度可读性,也可以保证数据的安全性。
ICP备案:
公安联网备案: