一文帶你搞懂Vue3中的各種ref的使用
在 Vue3 中,有許多與響應(yīng)式相關(guān)的函數(shù),例如 toRef、toRefs、isRef、unref 等等。合理地使用這些函數(shù)可以在實(shí)際開發(fā)中大大提高效率。本文將詳細(xì)介紹這些函數(shù)的用法,讓我們?cè)趯?shí)際開發(fā)中知道應(yīng)該使用哪些 API 并能夠熟練地回答面試官的相關(guān)問(wèn)題。
ref()
大家對(duì)于 ref 這個(gè) API 肯定都不陌生。在 Vue3 中經(jīng)常會(huì)用到它。它的作用是接收一個(gè)值并返回一個(gè)響應(yīng)式的對(duì)象。我們可以通過(guò).value 屬性來(lái)訪問(wèn)和修改這個(gè)值。在模板中,我們可以省略.value,例如在下面的代碼中,當(dāng)點(diǎn)擊按鈕時(shí),頁(yè)面中的 count 會(huì)響應(yīng)式地更改。
<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 可以根據(jù)一個(gè)響應(yīng)式對(duì)象中的一個(gè)屬性,創(chuàng)建一個(gè)響應(yīng)式的 ref。同時(shí)這個(gè) ref 和原對(duì)象中的屬性保持同步,改變?cè)瓕?duì)象屬性的值這個(gè) ref 會(huì)跟著改變,反之改變這個(gè) ref 的值原對(duì)象屬性值也會(huì)改變,它接收兩個(gè)參數(shù),一個(gè)是響應(yīng)式對(duì)應(yīng),另一個(gè)則是屬性值,例如下面代碼
<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>
點(diǎn)擊按鈕的時(shí)候修改了 a 的值,此時(shí) count 中的 a 也會(huì)跟著修改,當(dāng)然這里的 count 也可以用 reactive
toRefs
toRefs 它可以將一個(gè)響應(yīng)式對(duì)象轉(zhuǎn)成普通對(duì)象,而這個(gè)普通對(duì)象的每個(gè)屬性都是響應(yīng)式的 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>
此時(shí)代碼中的countAsRefs
類型為
{ a: Ref<number>, b: Ref<number> }
它的屬性 a 和 b 都是響應(yīng)式的 ref 對(duì)象,同樣的它們和原對(duì)象的 count 的屬性也是保持同步的
根據(jù)它的特性我們通常用它來(lái)解構(gòu)一個(gè)響應(yīng)式對(duì)象而不會(huì)讓其失去響應(yīng)式
import { reactive, toRefs } from "vue"; const count = reactive({ a: 1, b: 2, }); const { a, b } = toRefs(count);
此時(shí)的 a 和 b 都是一個(gè)響應(yīng)式的 ref 對(duì)象,并和原對(duì)象的 a 和 b 屬性保持同步
isRef()
isRef 顧名思義它是用來(lái)判斷某個(gè)值是否是 ref,注意:它判斷不了這個(gè)值是不是 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()
其實(shí)它是一個(gè)語(yǔ)法糖
val = isRef(val) ? val.value : val;
如果是 ref 則返回它的內(nèi)部值,否則則返回它本身。通過(guò)這個(gè)語(yǔ)法糖我們可以看出它可以對(duì)響應(yīng)式對(duì)象解除響應(yīng)式引用,比如我們只想獲取一個(gè)響應(yīng)式的值,但不想要它的響應(yīng)式可以使用它解除引用。 例如
<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 是不具備響應(yīng)式的
shallowRef
通過(guò)翻譯我們可以看出它是淺層的 ref,什么是淺層的 ref 呢? 與 ref 不同的是只有.value 是響應(yīng)式的,再深層的屬性則不具備響應(yīng)式
<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 = () => { //不會(huì)觸發(fā)頁(yè)面更新 shallowObj.value.a++ } </script>
但是如果我們將 addCount 改為修改整個(gè).value 就會(huì)觸發(fā)響應(yīng)式了
const addCount = () => { let temp = shallowObj.value.a; temp++; shallowObj.value = { a: temp, }; };
triggerRef
它可以讓淺層的 ref 即 shallowRef 深層屬性發(fā)生改變的時(shí)候強(qiáng)制觸發(fā)更改,比如上面觸發(fā)不了響應(yīng)式的代碼示例加入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強(qiáng)制觸發(fā)更改 triggerRef(shallowObj) } </script>
此時(shí)再看頁(yè)面效果則觸發(fā)了響應(yīng)式
customRef
顧名思義它是自定義的 ref,我們可以通過(guò) customRef 來(lái)顯式的追蹤某個(gè)值的響應(yīng)式變化,它接收一個(gè)函數(shù),這個(gè)函數(shù)接受 track 和 trigger 兩個(gè)函數(shù)作為參數(shù),并返回一個(gè)帶有 get 和 set 方法的對(duì)象。比如下面封裝一個(gè)自定義的響應(yīng)式對(duì)象 myRef,同時(shí)控制它只有值小于 4 才會(huì)觸發(fā)響應(yīng)式
<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需要追蹤后續(xù)內(nèi)容的變化,這里可以自由控制 track() return value }, set(newValue) { console.log(newValue);//myRef.value=xxx的xxx值 //加trigger則觸發(fā)響應(yīng)式,通知vue更新頁(yè)面,這里可以自由控制是否加trigger if(value<4) trigger() value = newValue } } }) return customValue } const count = myRef(0) const addCount = () => { count.value++ } </script>
可以看到當(dāng) count 大于 4 的時(shí)候便失去了響應(yīng)式
總結(jié)
本篇文章詳細(xì)介紹了 Vue3 中各種 ref 的用法,其中包括
- ref(): 接收一個(gè)值并返回一個(gè)響應(yīng)式的對(duì)象,可以使用.value 屬性來(lái)訪問(wèn)和修改這個(gè)值。
- toRef(obj, key): 根據(jù)一個(gè)響應(yīng)式對(duì)象中的一個(gè)屬性,創(chuàng)建一個(gè)響應(yīng)式的 ref,并且該 ref 和原對(duì)象中的屬性保持同步。
-toRefs(obj): 將一個(gè)響應(yīng)式對(duì)象轉(zhuǎn)換成一個(gè)普通對(duì)象,其中普通對(duì)象的每個(gè)屬性都是響應(yīng)式的 ref。 - isRef(value): 判斷某個(gè)值是否是 ref 對(duì)象。
- unref(value): 用于解除響應(yīng)式引用
- shallowRef(value): 創(chuàng)建一個(gè)淺層的 ref,只有 value 屬性是響應(yīng)式的,深層的屬性不具備響應(yīng)式。
- triggerRef(ref): 強(qiáng)制淺層的 ref 發(fā)生改變時(shí)觸發(fā)響應(yīng)式。
- customRef(factory): 自定義 ref 對(duì)象,可以顯式地追蹤某個(gè)值的響應(yīng)式變化。
到此這篇關(guān)于一文帶你搞懂Vue3中的各種ref的使用的文章就介紹到這了,更多相關(guān)Vue3 ref內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue解決移動(dòng)端彈窗滾動(dòng)穿透問(wèn)題
這篇文章主要介紹了Vue解決移動(dòng)端彈窗滾動(dòng)穿透問(wèn)題的方法,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12vscode不支持nvue語(yǔ)法高亮的解決辦法(圖文詳解)
這篇文章主要介紹了vscode不支持nvue語(yǔ)法高亮的解決辦法,用vscode開發(fā)uniapp會(huì)遇到用.nvue開發(fā)的時(shí)候。但是vscode并沒(méi)有提供.nvue的語(yǔ)法高亮,這篇文章給剛用vscode寫.nvue的讀者,需要的朋友可以參考下2023-02-02Vue?keepAlive實(shí)現(xiàn)不同的路由共用一個(gè)組件component的緩存問(wèn)題(推薦)
這篇文章主要介紹了Vue?keepAlive實(shí)現(xiàn)不同的路由共用一個(gè)組件component的緩存問(wèn)題,實(shí)現(xiàn)方式使用Vue?keepAlive實(shí)現(xiàn)頁(yè)面緩存,需要的朋友可以參考下2022-08-08vue3實(shí)現(xiàn)按鈕權(quán)限管理的項(xiàng)目實(shí)踐
在做后臺(tái)管理系統(tǒng)時(shí),經(jīng)常會(huì)有權(quán)限管理的功能,本文主要介紹了vue3實(shí)現(xiàn)按鈕權(quán)限管理的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08Vue循環(huán)組件加validate多表單驗(yàn)證的實(shí)例
今天小編就為大家分享一篇Vue循環(huán)組件加validate多表單驗(yàn)證的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue如何基于el-table實(shí)現(xiàn)多頁(yè)多選及翻頁(yè)回顯過(guò)程
在最近的一個(gè)項(xiàng)目中我需要實(shí)現(xiàn)表格的翻頁(yè),并且還要實(shí)現(xiàn)全選、多選功能,下面這篇文章主要給大家介紹了關(guān)于vue如何基于el-table實(shí)現(xiàn)多頁(yè)多選及翻頁(yè)回顯過(guò)程的相關(guān)資料,需要的朋友可以參考下2022-12-12