在 Vue3 中,有許多與響應式相關的函數,例如 toRef、toRefs、isRef、unref 等等。合理地使用這些函數可以在實際開發中大大提高效率。本文將詳細介紹這些函數的用法,讓我們在實際開發中知道應該使用哪些 API 並能夠熟練地回答面試官的相關問題。 ## ref() 大家對於 ref ...
在 Vue3 中,有許多與響應式相關的函數,例如 toRef、toRefs、isRef、unref 等等。合理地使用這些函數可以在實際開發中大大提高效率。本文將詳細介紹這些函數的用法,讓我們在實際開發中知道應該使用哪些 API 並能夠熟練地回答面試官的相關問題。
ref()
大家對於 ref 這個 API 肯定都不陌生。在 Vue3 中經常會用到它。它的作用是接收一個值並返回一個響應式的對象。我們可以通過.value 屬性來訪問和修改這個值。在模板中,我們可以省略.value,例如在下麵的代碼中,當點擊按鈕時,頁面中的 count 會響應式地更改。
<template>
<div>
{{ count }}
<button @click="addCount">+1</button>
</div>
</template>
<script lang='ts' setup>
import { ref } from "vue"
const count = ref(1)
const addCount = () => {
count.value++
}
</script>
toRef
toRef 可以根據一個響應式對象中的一個屬性,創建一個響應式的 ref。同時這個 ref 和原對象中的屬性保持同步,改變原對象屬性的值這個 ref 會跟著改變,反之改變這個 ref 的值原對象屬性值也會改變,它接收兩個參數,一個是響應式對應,另一個則是屬性值,例如下麵代碼
<template>
<div>
{{ count.a }}
{{ a }}
<button @click="addCount">+1</button>
</div>
</template>
<script lang='ts' setup>
import { ref, toRef } from "vue"
const count = ref({
a: 1,
b: 2
})
const a = toRef(count.value, 'a')
const addCount = () => {
a.value++
}
</script>
點擊按鈕的時候修改了 a 的值,此時 count 中的 a 也會跟著修改,當然這裡的 count 也可以用 reactive
toRefs
toRefs 它可以將一個響應式對象轉成普通對象,而這個普通對象的每個屬性都是響應式的 ref
<template>
<div>
{{ count.a }}
{{ countAsRefs.a }}
<button @click="addCount">+1</button>
</div>
</template>
<script lang='ts' setup>
import { reactive, toRefs } from "vue"
const count = reactive({
a: 1,
b: 2
})
const countAsRefs = toRefs(count)
const addCount = () => {
countAsRefs.a.value++
}
</script>
此時代碼中的countAsRefs
類型為
{
a: Ref<number>,
b: Ref<number>
}
它的屬性 a 和 b 都是響應式的 ref 對象,同樣的它們和原對象的 count 的屬性也是保持同步的
根據它的特性我們通常用它來解構一個響應式對象而不會讓其失去響應式
import { reactive, toRefs } from "vue";
const count = reactive({
a: 1,
b: 2,
});
const { a, b } = toRefs(count);
此時的 a 和 b 都是一個響應式的 ref 對象,並和原對象的 a 和 b 屬性保持同步
isRef()
isRef 顧名思義它是用來判斷某個值是否是 ref,註意:它判斷不了這個值是不是 reactive(可以使用 isReactive 判斷)
import { reactive, isRef, ref } from "vue";
const count = ref(1);
const testObj = reactive({
a: 1,
});
console.log(isRef(count)); //true
console.log(isRef(testObj)); //false
unref()
其實它是一個語法糖
val = isRef(val) ? val.value : val;
如果是 ref 則返回它的內部值,否則則返回它本身。通過這個語法糖我們可以看出它可以對響應式對象解除響應式引用,比如我們只想獲取一個響應式的值,但不想要它的響應式可以使用它解除引用。 例如
<template>
<div>
{{ unRefAsCount }}
{{ count }}
<button @click="addCount">+1</button>
</div>
</template>
<script lang='ts' setup>
import { unref, ref } from "vue"
const count = ref(1)
let unRefAsCount = unref(count)
const addCount = () => {
count.value++
}
</script>
代碼中的 unRefAsCount 是不具備響應式的
shallowRef
通過翻譯我們可以看出它是淺層的 ref,什麼是淺層的 ref 呢? 與 ref 不同的是只有.value 是響應式的,再深層的屬性則不具備響應式
<template>
<div>
{{ shallowObj.a }}
<button @click="addCount"> +1</button>
</div>
</template>
<script lang='ts' setup>
import { shallowRef } from "vue"
const shallowObj = shallowRef({
a: 1
})
const addCount = () => {
//不會觸發頁面更新
shallowObj.value.a++
}
</script>
但是如果我們將 addCount 改為修改整個.value 就會觸發響應式了
const addCount = () => {
let temp = shallowObj.value.a;
temp++;
shallowObj.value = {
a: temp,
};
};
triggerRef
它可以讓淺層的 ref 即 shallowRef 深層屬性發生改變的時候強制觸發更改,比如上面觸發不了響應式的代碼示例加入triggerRef
後
<template>
<div>
{{ shallowObj.a }}
<button @click="addCount"> +1</button>
</div>
</template>
<script lang='ts' setup>
import { shallowRef, triggerRef } from "vue"
const shallowObj = shallowRef({
a: 1
})
const addCount = () => {
shallowObj.value.a++
//加入triggerRef強制觸發更改
triggerRef(shallowObj)
}
</script>
此時再看頁面效果則觸發了響應式
customRef
顧名思義它是自定義的 ref,我們可以通過 customRef 來顯式的追蹤某個值的響應式變化,它接收一個函數,這個函數接受 track 和 trigger 兩個函數作為參數,並返回一個帶有 get 和 set 方法的對象。比如下麵封裝一個自定義的響應式對象 myRef,同時控制它只有值小於 4 才會觸發響應式
<template>
<div>
{{ count }}
<button @click="addCount"> +1</button>
</div>
</template>
<script lang='ts' setup>
import { customRef } from "vue"
const myRef = (value: number) => {
const customValue = customRef((track, trigger) => {
return {
get() {
//通知vue需要追蹤後續內容的變化,這裡可以自由控制
track()
return value
},
set(newValue) {
console.log(newValue);//myRef.value=xxx的xxx值
//加trigger則觸發響應式,通知vue更新頁面,這裡可以自由控制是否加trigger
if(value<4) trigger()
value = newValue
}
}
})
return customValue
}
const count = myRef(0)
const addCount = () => {
count.value++
}
</script>
可以看到當 count 大於 4 的時候便失去了響應式
總結
本篇文章詳細介紹了 Vue3 中各種 ref 的用法,其中包括
- ref(): 接收一個值並返回一個響應式的對象,可以使用.value 屬性來訪問和修改這個值。
- toRef(obj, key): 根據一個響應式對象中的一個屬性,創建一個響應式的 ref,並且該 ref 和原對象中的屬性保持同步。
-toRefs(obj): 將一個響應式對象轉換成一個普通對象,其中普通對象的每個屬性都是響應式的 ref。 - isRef(value): 判斷某個值是否是 ref 對象。
- unref(value): 用於解除響應式引用
- shallowRef(value): 創建一個淺層的 ref,只有 value 屬性是響應式的,深層的屬性不具備響應式。
- triggerRef(ref): 強制淺層的 ref 發生改變時觸發響應式。
- customRef(factory): 自定義 ref 對象,可以顯式地追蹤某個值的響應式變化。
如果本篇文章對你有所幫助的話那就點個贊吧~