1.ref
ref的主要作用就是將一個(gè)變量變成響應(yīng)式變量。在vue3中,隨處定義的變量并不是響應(yīng)式的,也就是說,如果模板中渲染了這個(gè)變量,那這個(gè)變量其實(shí)是不會(huì)驅(qū)使視圖變更的。
看個(gè)例子
<template>
{{message}}
<button @click="checkBut('大王')">測試</button>
</template>
<script setup lang="ts">
let message:string = '小王'
function checkBut(val:string) {
message = val
console.log(message) //輸出大王
}
</script>
修改了message這個(gè)變量,值變化了,但是模板卻并沒有發(fā)生變化。
這個(gè)時(shí)候就需要用到ref這個(gè)api了。
import {ref} from 'vue'
let message:string = ref('小王')
function checkBut(val:string) {
message.value = val
console.log(message)
}
ref會(huì)返回一個(gè)響應(yīng)式且可變的 ref 對象。ref 對象僅有一個(gè) .value property,指向該內(nèi)部值。

這樣message就會(huì)變成一個(gè)響應(yīng)式變量。但是在js代碼中去訪問需要通過.value的方式去訪問這個(gè)響應(yīng)式值。
同樣的,此api也可以將一個(gè)對象變成響應(yīng)式的,但是訪問也需要通過.value的形式。
2.isRef
檢查值是否是一個(gè)ref對象。是則返回true,不是則返回false
3.unref
語法糖,如果值是一個(gè)ref對象則返回此對象,如果不是則返回參數(shù)本身。
val = unref(val)等于 val = isRef(val)?val.value:val
4.shallowRef
官網(wǎng)解釋:創(chuàng)建一個(gè)跟蹤自身 .value 變化的 ref,但不會(huì)使其值也變成響應(yīng)式的。
大概意思就是創(chuàng)建一個(gè)ref,但是這個(gè)ref只跟蹤到.value,不會(huì)再深入去跟蹤。
如果這個(gè)api只作用于基本數(shù)據(jù)類型那和ref的效果一樣,但是如果傳入的是引用類型,則會(huì)大有不同
<template>
{{obj}}
</template>
<script setup lang="ts">
import {ref,shallowRef} from 'vue'
let obj = shallowRef({
name:'小王'
})
console.log(obj)
setTimeout(()=>{
obj.value.name = '456'
console.log(obj) //此時(shí)name已經(jīng)被修改了,但是試圖并不會(huì)發(fā)生變化,
//因?yàn)閚ame屬性不是響應(yīng)式的了,
},1500)
</script>

而當(dāng)我們?nèi)バ薷恼麄€(gè)value的時(shí)候,試圖就會(huì)發(fā)生變化
import {ref,shallowRef} from 'vue'
let obj = shallowRef({
name:'小王'
})
console.log(obj)
setTimeout(()=>{
obj.value.name = '456'
console.log(obj)
},1500)
setTimeout(()=>{
obj.value = '456'
console.log(obj)
},2000)

5.triggerRef
強(qiáng)制更新與shallowRef相關(guān)的屬性。
import {ref,shallowRef,triggerRef} from 'vue'
let obj = shallowRef({
name:'小王'
})
console.log(obj)
setTimeout(()=>{
obj.value.name = '456'
triggerRef(obj)
console.log(obj)
},1500)
這樣,試圖就會(huì)被更新了
6.customRef
創(chuàng)建一個(gè)自定義的ref,有點(diǎn)類似Object.defineProperty。customRef也提供了set和get,我們可以自定義相應(yīng)事件。
官方解釋:創(chuàng)建一個(gè)自定義的 ref,并對其依賴項(xiàng)跟蹤和更新觸發(fā)進(jìn)行顯式控制。它需要一個(gè)工廠函數(shù),該函數(shù)接收 track 和 trigger 函數(shù)作為參數(shù),并且應(yīng)該返回一個(gè)帶有 get 和 set 的對象。
<template>
{{msg}}
<button @click="handleCheckBut">測試</button>
</template>
<script setup lang="ts">
import {ref,shallowRef,triggerRef,customRef} from 'vue'
function f(value) {
return customRef((track, trigger)=>{
return{
get(){
console.log('get')
track() //收集依賴
return value
},
set(newval){
console.log('set',newval)
value = newval
setTimeout(()=>{
trigger() //觸發(fā)更新
},1000)
},
}
})
}
let msg = f('哈哈')
function handleCheckBut() {
msg.value = '嘿嘿'
}
</script>
注意這個(gè)函數(shù)返回的也是個(gè)ref對象,賦值的時(shí)候也要通過.value去賦值。
此方法好像只能給基本類型用,引用類型屬性修改了并沒辦法跟蹤到