学习vue3第七节其他常用api

本文主要介绍以下api
readonly()、isReadonly()、shallowReadonly()、isProxy()、toRaw()、markRaw()

1、readonly()

接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理

只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与 reactive() 相同,但解包得到的值是只读的。

要避免深层级的转换行为,请使用 shallowReadonly() 作替代。

注意:readonly函数只能将一个对象转换为只读对象,而不能将一个数组或Map等其他类型的数据结构转换为只读对象

csharp 复制代码
<script setup>
  let person = reactive({
    job: '搬砖',
    love: '象棋'
  })

  const readObj = readonly(person)

  const handleChangeJOb = () => {

    // person.job = '躺平' // 源代理对象person依然是响应式对象,可以进行更改
    readObj.job = '搬不动了' // 代理对象readObj是只读对象,不能进行更改
     // 但是 如何同时修改源代理对象 person 和只读对象readObj 的相同属性 job时,依然可以触发视图中 readObj.job的视图进行更新
     如果强制修改只读属性,会报错
  }
</script>

2、shallowReadonly()

shallowReadonly()同readonly()一样都是将一个对象转换为只读对象,但是shallowReadonly()不会对嵌套对象进行转换,只会对最外层对象进行转换,即只能将根级别属性转换为只读,而深层嵌套的属性,依然原样存储保留,原来的响应式

csharp 复制代码
<script setup>
  let person = reactive({
    job: '搬砖',
    love: '象棋',
    others: {
      name: '张三',
      age: 18
    }
  })
  // 转换为浅层只读对象
  const shallRed = shallowReadonly(person)
  // shallRed.love = '跑步' // shallowReadonly创建的对象shallRed是浅读对象,根级别属性,love不能进行修改,修改时候会报错
  shallRed.others.name = `${shallRed.others.name}+$` // 而是  // shallowReadonly创建的对象shallRed是浅读对象,深层级别属性,others.name可以进行修改,可以触发视图更新
</script>

3、isReadonly()

校验传入的对象是否为只读对象,返回一个布尔值;比如使用readonly() 和 shallowReadonly() 创建的对象,都可以通过isReadonly()进行校验,校验而获取 ture

csharp 复制代码
<script setup>
let shallObj = shallowReadonly({
  job: '搬砖',
  love: '象棋',
  others: {
    name: '张三',
    age: 18
  }
})
const isShall = isReadonly(shallObj) // true
</script>

4、isProxy()

校验传入的对象是否为代理对象,返回一个布尔值;比如使用reactive()、shallowReactive()、 readonly()、shallowReadonly() 创建的对象,都可以通过isProxy()进行校验,校验而获取 ture

注意:只有针对vue3 创建的响应式对象才会返回true;如果使用new Proxy()创建的对象,isProxy()返回false;

csharp 复制代码
<script setup>
  let person = reactive({
    job: '搬砖',
    love: '象棋',
    others: {
      name: '张三',
      age: 18
    }
  })
  const isPerson = isProxy(person) // true

  // 自定义代理对象,详细描述请查看 MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
  let person2 = new Proxy({}, {
    get(target, key, receiver) {
      retrun Reflect.get(target, key, receiver) || target[key]
    },
    set(target, key, value, receiver) {
      return Reflect.set(target, key, value, receiver) || target[key] = value
    }
  })
  const isPerson2 = isProxy(person2) // false
</script>

5、toRaw()

将一个代理对象转换为原值,返回一个原值;即不会更新UI视图

应用场景:比如,ref/reactive 创建的响应式数据类型每次修改都会被追踪,都会更新UI界面,但是这样是非常消耗性能的,假如我们有一些操作不需要追踪,不需要更新UI界面,那么这个时候我们就可以通过toRaw方法拿到它的原始数据,对原始数据进行修改,这样就不会被追踪,这样就不会更新UI界面,这样性能就好了。

csharp 复制代码
<template>
  <br>
  pObj:{{ pObj }}
  <br>
  rawObj:{{ pObj }}
  <br>
  <button @click="handleChangePobj">Pobj</button>
</template>

  <script setup>
  import { reactive, toRaw } from 'vue'
  const baseObj = {
  name: 'Andy',
  age: 18,
  job: '梦想躺平'
}
let pObj = reactive(baseObj)
let rawObj = toRaw(baseObj)

const handleChangePobj = () => {
  rawObj.name = '王五'
  
  console.log('=rawObj==', rawObj) // 单独操作rawObj.name时; 更改了原始对象,值发生了改变,但是视图不会更新
  console.log('=pObj==', pObj) // 会发现操作rawObj.name时,pObj.name并没有更新,因为pObj是reactive创建的响应式对象,但是rawObj是toRaw创建的原始对象,所以pObj.name,值发是勒改变,但是视图并没有更新
}
  </script>

6、markRaw()

讲一个对象标记为不可转化为响应式代理对象,并且返回对象本身

markRaw() 与 toRaw() 互为对应,markRaw() 会将一个对象标记为不可转化为响应式代理对象,并且返回对象本身;

比如:

1.在一些第三方库引用中,第三方的库是不需要响应式的;

2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能

3.在动态渲染组件的时候我们就可以使用 markRaw 包裹。

csharp 复制代码
<script setup>
  import { reactive, markRaw } from 'vue'
  const baseObj = {
  name: 'Andy',
  age: 18,
  job: '梦想躺平'
}
let pObj = reactive(baseObj)
let rawObj = markRaw(baseObj)

const handleChangePobj = () => {
  rawObj.name = '王五'
  
  console.log('=rawObj==', rawObj) // 单独操作rawObj.name,发现视图是不会更新的;因为markRaw() 创建的是非响应式的对象;
}
let pObj2 = reactive({
  name: 'Andy',
  age: 18,
  job: '梦想躺平'
})
pObj2['otherJob'] = markRaw({otherJob: '搬砖'}) // 此时pObj2['otherJob'] 会变成非响应式对象,不会被追踪,不会更新视图,而其他属性依然是响应式的;
</script>
相关推荐
井队Tell几秒前
打造高清3D虚拟世界|零基础学习Unity HDRP高清渲染管线(第五天)
学习·3d·unity
烛阴几秒前
循环背后的魔法:Lua 迭代器深度解析
前端·lua
元拓数智14 分钟前
现代前端状态管理深度剖析:从单一数据源到分布式状态
前端·1024程序员节
mapbar_front17 分钟前
Electron 应用自动更新方案:electron-updater 完整指南
前端·javascript·electron
sensen_kiss31 分钟前
INT301 Bio-computation 生物计算(神经网络)Pt.2 监督学习模型:感知器(Perceptron)
神经网络·学习·机器学习
天一生水water1 小时前
three.js加载三维GLB文件,查看三维模型
前端·1024程序员节
无风听海1 小时前
HarmonyOS之启动应用内的UIAbility组件
前端·华为·harmonyos
Han.miracle1 小时前
数据结构——排序的超级详解(Java版)
java·数据结构·学习·算法·leetcode·排序算法·1024程序员节
冰夏之夜影1 小时前
【科普】Edge出问题后如何恢复出厂设置
前端·edge
W.Buffer2 小时前
设计模式-单例模式:从原理到实战的三种经典实现
开发语言·javascript·单例模式