一文搞懂Vue3中toRef和toRefs的區(qū)別
上面這段代碼中:
- 我們使用 reactive 創(chuàng)建了一個(gè)名為 info 的響應(yīng)式對象,包含 name 和 age 屬性。
- 然后使用 toRef 函數(shù)將 info 對象的 age 屬性轉(zhuǎn)換為一個(gè)獨(dú)立的 ref 對象。
- 接著定義了兩個(gè)方法 updateInfoObjAge 和 updateAge,分別用于更新 info 對象的 age 屬性和 age 引用的值。
從上面的代碼中,我們可以看到,age 屬性是使用 toRef 函數(shù)轉(zhuǎn)換的具有響應(yīng)式的 ref 屬性,當(dāng)我們更新時(shí),使用 reactive 定義的響應(yīng)式對象 info 中的 age 也會(huì)隨著更新。
<script setup>
import { reactive } from 'vue';
let info = reactive({
name: 'Echo',
age: 26,
gender: 'Male',
})
// 這樣解構(gòu)會(huì)丟失響應(yīng)式效果
let { name, age, gender } = info;
</script>下面,我們一起看看 toRef 和 toRefs 的用法:
1. toRef
- toRef 函數(shù)可以將一個(gè)響應(yīng)式對象的屬性轉(zhuǎn)換為一個(gè)獨(dú)立的 ref 對象。
- 返回的是一個(gè)指向源對象屬性的 ref 引用,任何對該引用的修改都會(huì)同步到源對象屬性上。
- 使用 toRef 時(shí)需要傳入源對象和屬性名作為參數(shù)。
下面我們一起看一段代碼:
<script setup>
import { reactive, toRef } from 'vue';
let info = reactive({
name: 'Echo',
age: 26,
})
let age = toRef(info, 'age');
const updateInfoObjAge = () => {
info.age++;
}
const updateAge = () => {
age.value++;
}
</script>
<template>
<div id="app">
<p>info對象中的age:{{ info.age }}</p>
<button @click="updateInfoObjAge">更新info對象中的 age</button>
<br />
<p>使用toRef函數(shù)轉(zhuǎn)換后的age:{{ age }}</p>
<button @click="updateAge">更新 age</button>
</div>
</template>上面這段代碼中:
- 我們使用 reactive 創(chuàng)建了一個(gè)名為 info 的響應(yīng)式對象,包含 name 和 age 屬性。
- 然后使用 toRef 函數(shù)將 info 對象的 age 屬性轉(zhuǎn)換為一個(gè)獨(dú)立的 ref 對象。
- 接著定義了兩個(gè)方法 updateInfoObjAge 和 updateAge,分別用于更新 info 對象的 age 屬性和 age 引用的值。
從上面的代碼中,我們可以看到,age 屬性是使用 toRef 函數(shù)轉(zhuǎn)換的具有響應(yīng)式的 ref 屬性,當(dāng)我們更新時(shí),使用 reactive 定義的響應(yīng)式對象 info 中的 age 也會(huì)隨著更新。

而且,從開發(fā)工具中,我們也可以看到,age 屬性是一個(gè)具有 ref 響應(yīng)式的屬性。

2. toRefs
- toRefs 函數(shù)可以將一個(gè)響應(yīng)式對象轉(zhuǎn)換為一個(gè)普通的對象,該對象的每個(gè)屬性都是獨(dú)立的 ref 對象。
- 返回的對象可以進(jìn)行解構(gòu),每個(gè)屬性都可以像普通的 ref 對象一樣訪問和修改,而且會(huì)保持響應(yīng)式的關(guān)聯(lián)。
- toRefs 的使用場景主要是在將響應(yīng)式對象作為屬性傳遞給子組件時(shí),確保子組件可以正確地訪問和更新這些屬性。
下面我們一起看一段代碼:
<script setup>
import { reactive, toRefs } from 'vue';
let info = reactive({
name: 'Echo',
age: 26,
gender: 'Male',
})
let { name, age, gender } = toRefs(info);
const update = () => {
name.value = 'Julie';
age.value = 33;
gender.value = 'Female';
}
</script>
<template>
<div id="app">
<p>info對象中的name:{{ info.name }}</p>
<p>info對象中的age:{{ info.age }}</p>
<p>info對象中的gender:{{ info.gender }}</p>
<br />
<p>解構(gòu)出來的name:{{ name }}</p>
<p>解構(gòu)出來的age:{{ age }}</p>
<p>解構(gòu)出來的gender:{{ gender }}</p>
<button @click="update">更新數(shù)據(jù)</button>
</div>
</template>上面這段代碼中:
- 首先,使用 reactive 函數(shù)創(chuàng)建了一個(gè)響應(yīng)式對象 info,包含了 name、age 和 gender 三個(gè)屬性,同時(shí)設(shè)置了初始值。
- 接著,使用 toRefs 函數(shù)將 info 對象轉(zhuǎn)換為多個(gè)獨(dú)立的響應(yīng)式引用對象。然后通過解構(gòu)賦值,把 name、age 和 gender 三個(gè)響應(yīng)式引用對象分別賦給了相應(yīng)的變量。
- 最后,添加了一個(gè)按鈕,點(diǎn)擊按鈕會(huì)觸發(fā) update 函數(shù),在 update 函數(shù)中,通過修改響應(yīng)式引用對象的 value 屬性來更新數(shù)據(jù)的值。

從開發(fā)工具中,我們可以看到,解構(gòu)出來的每個(gè)屬性,都是獨(dú)立的具有 ref 響應(yīng)式的屬性,因此,我們需要使用 .value 才能訪問和修改其值。

3. 相同點(diǎn)
- toRef 和 toRefs 都用于將響應(yīng)式對象的屬性轉(zhuǎn)換為 ref 對象。
- 轉(zhuǎn)換后的屬性仍然保持響應(yīng)式,對屬性的修改會(huì)反映到源對象上。
- 不管是使用 toRef 還是 toRefs 將響應(yīng)式對象轉(zhuǎn)成普通對象,在 script 中修改和訪問其值都需要通過 .value 進(jìn)行。
4. 不同點(diǎn)
- toRef 修改的是對象的某個(gè)屬性,生成一個(gè)單獨(dú)的 ref 對象。
- toRefs 修改的是整個(gè)對象,生成多個(gè)獨(dú)立的 ref 對象集合。
- toRefs 適用于在組件傳遞屬性或解構(gòu)時(shí)使用,更加方便靈活,而 toRef 更適合提取單個(gè)屬性進(jìn)行操作。
通過上面對 toRef 和 toRefs 函數(shù)的了解,你們知道為什么需要 toRef 和 toRefs 了嗎?
總結(jié)起來就是:在不丟失響應(yīng)式的前提下,對響應(yīng)式對象數(shù)據(jù)進(jìn)行解構(gòu),這樣如果在 setup 中返回 toRefs(obj),或者 toRef(obj, 'xxx'),我們就可以在 template 中不使用 obj.xxx 來取值了。
以上就是一文搞懂Vue3中toRef和toRefs的區(qū)別的詳細(xì)內(nèi)容,更多關(guān)于Vue3 toRef和toRefs區(qū)別的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
淺析vue偵測數(shù)據(jù)的變化之基本實(shí)現(xiàn)
這里涉及到Vue一個(gè)重要特性:響應(yīng)式系統(tǒng)。數(shù)據(jù)模型只是普通的 JavaScript對象,當(dāng)我們修改時(shí),視圖會(huì)被更新,而變化偵測是響應(yīng)式系統(tǒng)的核心2021-06-06
詳解vue項(xiàng)目中調(diào)用百度地圖API使用方法
這篇文章主要介紹了vue項(xiàng)目中調(diào)用百度地圖API使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
前端JS也可以連點(diǎn)成線詳解(Vue中運(yùn)用AntVG6)
這篇文章主要給大家介紹了關(guān)于前端JS連點(diǎn)成線(Vue中運(yùn)用?AntVG6)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-01-01
vue怎樣獲取當(dāng)前時(shí)間,并且傳遞給后端(不用注解)
這篇文章主要介紹了vue怎樣獲得當(dāng)前時(shí)間,并且傳遞給后端(不用注解)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
vscode中prettier和eslint換行縮進(jìn)沖突的問題
這篇文章主要介紹了vscode中prettier和eslint換行縮進(jìn)沖突的問題及解決,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
vue項(xiàng)目中微信登錄的實(shí)現(xiàn)操作
這篇文章主要介紹了vue項(xiàng)目中微信登錄的實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
vite配置@別名以及讓vscode智能提示路經(jīng)的步驟
這篇文章主要給大家介紹了關(guān)于vite配置@別名以及讓vscode智能提示路經(jīng)的步驟,文中通過代碼示例以及圖文介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-08-08

