首页 > 编程笔记 > JavaScript笔记 阅读:9

Vue3 readonly()和shallowReadonly()函数的用法(附带实例)

Vue 中,无论是 reactive 对象(也称为代理对象)还是 ref 对象,进行的都是深度响应式处理。也就是说,我们通过 reactive 对象或 ref 对象进行属性的深度读取和修改操作,修改后能触发页面的自动更新。

如果我们想产生一个只包含读取能力的 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 代码运行后的页面效果


同时 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() 函数将数据进行只读转化,这样既可以保证程序的高度可读性,也可以保证数据的安全性。

相关文章