首页 > 编程笔记 > JavaScript笔记
阅读:9
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() 函数将数据进行只读转化,这样既可以保证程序的高度可读性,也可以保证数据的安全性。