学习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>
相关推荐
zwjapple1 小时前
docker-compose一键部署全栈项目。springboot后端,react前端
前端·spring boot·docker
DKPT2 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
像风一样自由20204 小时前
HTML与JavaScript:构建动态交互式Web页面的基石
前端·javascript·html
aiprtem4 小时前
基于Flutter的web登录设计
前端·flutter
浪裡遊4 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
好好研究4 小时前
学习栈和队列的插入和删除操作
数据结构·学习
why技术4 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
GISer_Jing4 小时前
0704-0706上海,又聚上了
前端·新浪微博
止观止5 小时前
深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案
前端·pnpm·前端工程化·包管理器
whale fall5 小时前
npm install安装的node_modules是什么
前端·npm·node.js