Vue3新特性的学习(六)

177 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

今天主要是学习readonly与shallowReadonly函数,toRaw与markRaw函数。

readonly

readonly深度只读数据,传入响应式或纯对象,返回一个原始对象的只读代理,对象内部任何嵌套的属性也都是只读的,在某些特定的情况下,不希望对数据进行更新的操作,那就可以包装生成一个只读代理对象来读取数据,防止对数据的修改或删除等操作

示例: 定义一个只读对象,当对只读对象中的属性进行修改或者删除的时候,就会报错:

<script lang="ts">
import { defineComponent, readonly } from "vue";
export default defineComponent({
  name: "readonly",
  setup() {
    let readState = readonly({
      a: 1,
      b: 2,
      c: {
        d: 4,
      },
    });
    readState.a += 1; // 浅层不能修改
    delete readState.c; // 浅层不能删除
    return {
        readState
    }
  },
});
</script>

image.png

shallowReadonly

shallowReadonly浅只读数据,传入响应式或者纯对象,返回一个原始对象的只读代理,但是这个只读只是第一层只读,非深度只读。

示例: 同样在使用shallowReadonly定义一个只读对象,当对只读对象中的属性进行修改或者删除的时候,a这个属性是第一层所以还是会报错;

在修改深层次的d属性的时候,是可以修改的;

let shallowReadState = shallowReadonly({
      a: 1,
      b: 2,
      c: {
        d: 4,
      },
    });
    shallowReadState.a += 3; // 浅层不能修改
    shallowReadState.c.d += 3; // 深层可以修改
    delete shallowReadState.c.d; // 深层可以删除
    console.log(shallowReadState)

不过删除d的时候也会报错,这时候我们还是可以解决这个问题的,在tsconfig.json中我们加上这样一句代码:"strictNullChecks":false,这时候去console,就发现d被删除了。 image.png

toRaw

toRaw可以将由reactive或者readonly函数转换成响应式代理的普通对象,对普通对象的属性值进行修改,就不会更新视图界面。一般用于渲染具有不可变数据源的大列表时,跳过代理转换可以提高性能。 示例:

<template>
  <div>
      <div>{{state.total}}</div>
      <button @click="update">更新数据</button>
  </div>
</template>
<script lang="ts">
import {
  defineComponent,
  readonly,
  shallowReadonly,
  reactive,
  toRaw,
} from "vue";
export default defineComponent({
  name: "readonly",
  setup() {
    let state = reactive({
      total: 10,
    });
    let update = () => {
      let stateRaw = state;
      stateRaw.total += 100;
    };
    return {
      state,
      update
    };
  },
});
</script>

此时更新数据是可以正常更新的,但是使用toRaw的时候,就不能更新state了,常用于,在数据还需要其他处理的时候,使用toRaw这样就不会再界面进行响应式更新了。

 let stateRaw = toRaw(state);

markRaw

markRaw标记一个对象 ,使其永远不会转换为响应式数据,只能返回这个对象本身,一般用于有些值不应被设置为响应式的,比如第三方实例或者Vue组件对象等场景。

    let markState = markRaw({
        arr:[1, 2,3]
    });
    let reactiveMarkState = reactive(markState);
    let updateMark = ()=> {
        reactiveMarkState.arr.push(4)
    }

一旦使用markRaw标记一个对象,就不能再使用reactive进行转换,不过使用toRaw标记后,是可以用reactive进行再转换为响应式数据。

接下来继续学习Vue3的知识点~