toRefs/toRef/unref/customRef
toRefs(reactiveObj)
解构reactive对象,返回对象中的属性都转为refs.保持数据响应式解构不丢失。
const info4=reactive({name:'zs',age:10}) // let {name,age}=info4 //直接解构失去了响应性 这是错误的写法 需要借助toRefs() let {name,age}=toRefs(info4) //会给我们返回两个ref对象 name age console.log(isRef(name),isRef(age)); //true true info4.name='zs~~~~~' //<==> name.value='zs~~~~~'完全等价,任何一个修改都会引起另外一个同步变化。很好
toRef(reactiveObj,key)
单个属性解构返回ref。可能会节约性能吧
const info4=reactive({name:'zs',age:10}) // toRef(reactiveObj,key) let name=toRef(info4,'name') // 单个解构返回ref name对象 name.vaue='sss'<==>info4.name='sss'完全等价 并且是响应式的 let age=info4.age //这是是普通的age,age=20修改值,age确实会被修改,但是不是响应式的,页面age数据不会发生变化
unref
unref(value|ref(value)) 如果是ref对象就返回ref.value数据,反之返回value本身。大白话就是返回基本值 unref本质 val = isRef(val) ? val.value : val
const useFoo=<T>(x:T|Ref<T>)=>{ return unref(x) } const r1=useFoo(ref('100')) //string const r3=useFoo(ref(100))
customRef
创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track
和 trigger
函数作为参数,并应返回一个带有 get
和 set
的对象。
自定义Ref
import { customRef } from "vue" const useDefouncedRef=(value:string,delay=2000)=>{ let timer:number|undefined=undefined return customRef((track,trigger)=>{ return { get(){ track() //收集依赖 return value }, set(newValue:string){ clearTimeout(timer) timer=setTimeout(()=>{ value=newValue trigger() },delay) } } }) } export default useDefouncedRef // const message=useDefouncedRef('hello world') //通常式const message=ref('hello world) // <input type="text" v-model="message">