Vue学习计划-Vue3--其他API:shallowRef与shallowReactive、readonly与shallowReadonly、toRaw与markRaw、customRef

时间:2024-01-25 14:10:08

其它 API

  1. shallowRefshallowReactive
  • shallowRef

    1. 作用:创建一个响应式数据,但只对顶层属性进行响应式处理。
    2. 用法:
    let myVar = shallowRef(initValue)
    
    1. 特点:只跟踪引用值的变化,不关心值内部的变化
  • shallowReactive

    1. 作用:创建一个浅层响应式对象,只会使对象的最顶层属性变成响应式的,对象内部的嵌套属性则不会变成响应式的
    2. 用法:
    let myVar = shallowReactive(initValue)
    
    1. 特点:对象的顶层属性是响应式的,但嵌套对象的属性不是。
  • 总结

通过使用 shallowRef()shallowReactive() 来绕开深度响应。浅层式 API 创建的状态只在其顶层是响应式的,对所有深层的对象不会做任何处理,避免了对每一个内部属性做响应式所带来的性能成本,这使得属性的访问变得更快,可提升性能。

  1. readonlyshallowReadonly
  • readonly
    1. 作用:用于创建一个对象的深只读副本。
    2. 用法:
    const original = reactive({...})
    const readOnlyCopy = readonly(original)
    
    1. 特点
    • 对象的所有嵌套属性都将变成只读
    • 任何尝试修改这个对象的操作都会被阻止(在开发模式下,还会在控制台中发出警告)
    1. 应用场景:
      • 创建不可变的状态快照
      • 保护全局状态或配置不被修改
  • shallowReadonly
    1. 作用:与readonly类似,但只作用于对象的顶层属性
    2. 用法:
    const original = reactive({...})
    const shallowReadonlyCopy = shallowReadonly(original)
    
    1. 特点:
      • 只将对象的顶层属性设置为只读,对象内部的嵌套属性仍然是可变的
      • 适用于只需保护对象顶层属性的场景
  1. toRawmarkRaw
  • toRaw

    1. 作用:用于获取一个响应式对象的原始对象, toRaw 返回的对象不再是响应式的,不会触发视图更新。

    官网描述:这是一个可以用于临时读取而不引起代理访问/跟踪开销,或是写入而不触发更改的特殊方法。不建议保存对原始对象的持久引用,请谨慎使用。

    何时使用? —— 在需要将响应式对象传递给非 Vue 的库或外部系统时,使用 toRaw 可以确保它们收到的是普通对象

    1. 具体代码
    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

    1. 作用:标记一个对象,使其永远不会变成响应式的。

    例如使用mockjs时,为了防止误把mockjs变为响应式对象,可以使用 markRaw 去标记mockjs

4.【customRef

  • 作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行逻辑控制。
  • 实现防抖效果,封装hooks
    1. 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
    }
    
    1. 组件中使用:
    <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>