其它 API
- 【
shallowRef
与shallowReactive
】
-
shallowRef
- 作用:创建一个响应式数据,但只对顶层属性进行响应式处理。
- 用法:
let myVar = shallowRef(initValue)
- 特点:只跟踪引用值的变化,不关心值内部的变化
-
shallowReactive
- 作用:创建一个浅层响应式对象,只会使对象的最顶层属性变成响应式的,对象内部的嵌套属性则不会变成响应式的
- 用法:
let myVar = shallowReactive(initValue)
- 特点:对象的顶层属性是响应式的,但嵌套对象的属性不是。
-
总结
通过使用 shallowRef() 和 shallowReactive() 来绕开深度响应。浅层式
API
创建的状态只在其顶层是响应式的,对所有深层的对象不会做任何处理,避免了对每一个内部属性做响应式所带来的性能成本,这使得属性的访问变得更快,可提升性能。
- 【
readonly
与shallowReadonly
】
-
readonly
- 作用:用于创建一个对象的深只读副本。
- 用法:
const original = reactive({...}) const readOnlyCopy = readonly(original)
- 特点
- 对象的所有嵌套属性都将变成只读
- 任何尝试修改这个对象的操作都会被阻止(在开发模式下,还会在控制台中发出警告)
- 应用场景:
- 创建不可变的状态快照
- 保护全局状态或配置不被修改
-
shallowReadonly
- 作用:与
readonly
类似,但只作用于对象的顶层属性 - 用法:
const original = reactive({...}) const shallowReadonlyCopy = shallowReadonly(original)
- 特点:
- 只将对象的顶层属性设置为只读,对象内部的嵌套属性仍然是可变的
- 适用于只需保护对象顶层属性的场景
- 作用:与
- 【
toRaw
与markRaw
】
-
toRaw
- 作用:用于获取一个响应式对象的原始对象,
toRaw
返回的对象不再是响应式的,不会触发视图更新。
官网描述:这是一个可以用于临时读取而不引起代理访问/跟踪开销,或是写入而不触发更改的特殊方法。不建议保存对原始对象的持久引用,请谨慎使用。
何时使用? —— 在需要将响应式对象传递给非
Vue
的库或外部系统时,使用toRaw
可以确保它们收到的是普通对象- 具体代码
import {reactive, toRaw, markRaw, isReactive} from 'vue' /* toRaw */ // 响应式对象 let person = reactive({name: 'mecy', age: 19}) // 原始对象 let rawPerson = toRaw(person) /* markRaw */ let nameArr = markRaw([ {id: '01', name: '小明'}, {id: '02', name: '小白'}, {id: '03', name: '小红'}, ]) // 根据原始对象nameArr去创建响应式对象 nameObj,创建失败,因为nameArr被markRaw标记了 let nameObj = reactive(nameArr) console.log(isReactive(person)) // true console.log(isReactive(rawPerson)) // false console.log(isReactive(nameArr)) // false console.log(isReactive(nameObj)) // false
- 作用:用于获取一个响应式对象的原始对象,
-
markRaw
- 作用:标记一个对象,使其永远不会变成响应式的。
例如使用
mockjs
时,为了防止误把mockjs
变为响应式对象,可以使用markRaw
去标记mockjs
4.【customRef
】
- 作用:创建一个自定义的
ref
,并对其依赖项跟踪和更新触发进行逻辑控制。 - 实现防抖效果,封装
hooks
-
useMsgRef.ts
:
import {customRef} from 'vue' export default function(initValue: string, delay: number) { let msg = customRef((tarck, trigger)=>{ let timer: number return { get(){ tarck() // 告诉Vue数据msg很重要,要对msg持续关注,一旦变化就更新 return initValue }, set(value){ clearTimeout(timer) timer = setTimeout(() => { initValue = value trigger()// 通知Vue数据msg变化了 }, delay) } } }) return msg }
- 组件中使用:
<template> <div> <div> <h2>{{ msg }}</h2> <input type="test" v-model="msg"/> </div> </div> </template> <script setup lang="ts" name="App"> import useMsgRef from './useMsgRef.ts' let msg = useMsgRef('初始值', 1000) </script>
-