Vue3關(guān)于響應(yīng)式數(shù)據(jù)類型詳解(ref、reactive、toRef、及toRefs)
ref
接受一個(gè)內(nèi)部值,返回一個(gè)響應(yīng)式的、可更改的 ref 對(duì)象,此對(duì)象只有一個(gè)指向其內(nèi)部值的 property .value。
類型
function ref<T>(value: T): Ref<UnwrapRef<T>> interface Ref<T> { value: T }
詳細(xì)信息
ref 對(duì)象是可更改的,也就是說你可以為 .value 賦予新的值。它也是響應(yīng)式的,即所有對(duì) .value 的操作都將被追蹤,并且寫操作會(huì)觸發(fā)與之相關(guān)的副作用。
如果將一個(gè)對(duì)象賦值給 ref,那么這個(gè)對(duì)象將通過 reactive() 轉(zhuǎn)為具有深層次響應(yīng)式的對(duì)象。這也意味著如果對(duì)象中包含了嵌套的 ref,它們將被深層地解包。
若要避免這種深層次的轉(zhuǎn)換,請(qǐng)使用 shallowRef() 來替代
示例
import { ref } from 'vue const count = ref<number>(0) console.log(count.value) // 0 count.value++ console.log(count.value) // 1
reactive
返回一個(gè)對(duì)象的響應(yīng)式代理
類型
function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
詳細(xì)信息
響應(yīng)式轉(zhuǎn)換是“深層”的:它會(huì)影響到所有嵌套的 property。一個(gè)響應(yīng)式對(duì)象也將深層地解包任何 ref property,同時(shí)保持響應(yīng)性。
值得注意的是,當(dāng)訪問到某個(gè)響應(yīng)式數(shù)組或 Map 這樣的原生集合類型中的 ref 元素時(shí),不會(huì)執(zhí)行 ref 的解包。
若要避免深層響應(yīng)式轉(zhuǎn)換,只想保留對(duì)這個(gè)對(duì)象頂層次訪問的響應(yīng)性,請(qǐng)使用 shallowReactive() 作替代。
返回的對(duì)象以及其中嵌套的對(duì)象都會(huì)通過 ES Proxy 包裹,因此不等于源對(duì)象,建議只使用響應(yīng)式代理,避免依賴于原始對(duì)象。
示例
import { reactive } from 'vue' interface Obj { count: number } const obj = reactive<Obj>({ count: 0 }) obj.count++
ref 的解包:
const count = ref(1) const obj = reactive({ count }) // ref 會(huì)被解包 console.log(obj.count === count.value) // true // 會(huì)更新 `obj.count` count.value++ console.log(count.value) // 2 console.log(obj.count) // 2 // 也會(huì)更新 `count` ref obj.count++ console.log(obj.count) // 3 console.log(count.value) // 3
注意當(dāng)訪問到某個(gè)響應(yīng)式數(shù)組或 Map 這樣的原生集合類型中的 ref 元素時(shí),不會(huì)執(zhí)行 ref 的解包
const books = reactive([ref('Vue 3 Guide')]) // 這里需要 .value console.log(books[0].value) const map = reactive(new Map([['count', ref(0)]])) // 這里需要 .value console.log(map.get('count').value)
將一個(gè) ref 賦值給為一個(gè) reactive 屬性時(shí),該 ref 會(huì)被自動(dòng)解包:
const count = ref(1) const obj = reactive({}) obj.count = count console.log(obj.count) // 1 console.log(obj.count === count.value) // true
toRef()
可用于為響應(yīng)式對(duì)象上的 property 創(chuàng)建 ref。這樣創(chuàng)建的 ref 與其源 property 保持同步:改變?cè)?property 將更新 ref,反之亦然。
類型
function toRef<T extends object, K extends keyof T>( object: T, key: K, defaultValue?: T[K] ): ToRef<T[K]> type ToRef<T> = T extends Ref ? T : Ref<T>
示例
const state = reactive({ foo: 1, bar: 2 }) const fooRef = toRef(state, 'foo') // 更改該 ref 會(huì)更新源屬性 fooRef.value++ console.log(state.foo) // 2 // 更改源屬性也會(huì)更新該 ref state.foo++ console.log(fooRef.value) // 3
請(qǐng)注意,這不同于:
const fooRef = ref(state.foo) //上面這個(gè) ref 不會(huì)和 state.foo 保持同步,因?yàn)檫@個(gè) ref() 接收到的是一個(gè)純數(shù)值。 //toRef() 這個(gè)函數(shù)在你想把一個(gè) prop 的 ref 傳遞給一個(gè)組合式函數(shù)時(shí)會(huì)很有用
<script setup> import { toRef } from 'vue' const props = defineProps(/* ... */) // 將 `props.foo` 轉(zhuǎn)換為 ref,然后傳入 // 一個(gè)組合式函數(shù) useSomeFeature(toRef(props, 'foo')) </script>
當(dāng) toRef 與組件 prop 結(jié)合使用時(shí),關(guān)于對(duì) prop 做出更改的通用限制依然有效。嘗試將新的值傳遞給 ref 等效于嘗試直接更改 prop,這是不允許的。在這種場(chǎng)景下,你可能可以考慮使用帶有 get 和 set 的 computed 替代。
即使源 property 當(dāng)前不存在,toRef() 也會(huì)返回一個(gè)可用的 ref。這讓它在處理可選 prop 的時(shí)候格外實(shí)用,而可選 prop 在使用 toRefs 時(shí)不會(huì)被保留。
toRefs()
將一個(gè)響應(yīng)式對(duì)象轉(zhuǎn)換為一個(gè)普通對(duì)象,這個(gè)普通對(duì)象的每個(gè) property 都是指向源對(duì)象相應(yīng) property 的 ref。每個(gè)單獨(dú)的 ref 都是使用 toRef() 創(chuàng)建的。
類型
function toRefs<T extends object>( object: T ): { [K in keyof T]: ToRef<T[K]> } type ToRef = T extends Ref ? T : Ref<T>
示例
const state = reactive({ foo: 1, bar: 2 }) const stateAsRefs = toRefs(state) /* stateAsRefs 的類型:{ foo: Ref<number>, bar: Ref<number> } */ // 這個(gè) ref 和源屬性已經(jīng)“鏈接上了” state.foo++ console.log(stateAsRefs.foo.value) // 2 stateAsRefs.foo.value++ console.log(state.foo) // 3
當(dāng)從組合式函數(shù)中返回響應(yīng)式對(duì)象時(shí),toRefs 大有作為,使用它,消費(fèi)者組件可以解構(gòu)/擴(kuò)展返回的對(duì)象而不會(huì)失去響應(yīng)性:
function useFeatureX() { const state = reactive({ foo: 1, bar: 2 }) // ...基于狀態(tài)的操作邏輯 // 在返回時(shí)都轉(zhuǎn)為 ref return toRefs(state) } // 可以解構(gòu)而不會(huì)失去響應(yīng)性 const { foo, bar } = useFeatureX()
toRefs 在調(diào)用時(shí)只會(huì)為源對(duì)象上可以列舉出的 property 創(chuàng)建 ref。如果要為可能還不存在的 property 創(chuàng)建 ref,請(qǐng)改用 toRef 。
到此這篇關(guān)于Vue3關(guān)于響應(yīng)式數(shù)據(jù)類型(ref、reactive、toRef、以及toRefs)的文章就介紹到這了,更多相關(guān)Vue3響應(yīng)式數(shù)據(jù)類型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue3.0使用ref和reactive來創(chuàng)建響應(yīng)式數(shù)據(jù)
- Vue3中使用ref與reactive創(chuàng)建響應(yīng)式數(shù)據(jù)的示例代碼
- Vue3 響應(yīng)式數(shù)據(jù) reactive使用方法
- vue3 reactive定義的引用類型直接賦值導(dǎo)致數(shù)據(jù)失去響應(yīng)式問題
- vue3中如何使用ref和reactive定義和修改響應(yīng)式數(shù)據(jù)(最新推薦)
- Vue 中 reactive創(chuàng)建對(duì)象類型響應(yīng)式數(shù)據(jù)的方法
相關(guān)文章
Vue computed實(shí)現(xiàn)原理深入講解
computed又被稱作計(jì)算屬性,用于動(dòng)態(tài)的根據(jù)某個(gè)值或某些值的變化,來產(chǎn)生對(duì)應(yīng)的變化,computed具有緩存性,當(dāng)無關(guān)值變化時(shí),不會(huì)引起computed聲明值的變化。產(chǎn)生一個(gè)新的變量并掛載到vue實(shí)例上去2022-10-10誤引用vuex-persistedstate導(dǎo)致用戶信息無法清除問題及解決
這篇文章主要介紹了誤引用vuex-persistedstate導(dǎo)致用戶信息無法清除問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue常用的數(shù)字孿生可視化的自適應(yīng)方案
這篇文章主要為大家介紹了vue常用的數(shù)字孿生可視化的自適應(yīng)方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07詳解VUE-地區(qū)選擇器(V-Distpicker)組件使用心得
這篇文章主要介紹了詳解VUE-地區(qū)選擇器(V-Distpicker)組件使用心得,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05Vux+Axios攔截器增加loading的問題及實(shí)現(xiàn)方法
這篇文章主要介紹了Vux+Axios攔截器增加loading的問題及實(shí)現(xiàn)方法,文中通過實(shí)例代碼介紹了vue中使用axios的相關(guān)知識(shí),需要的朋友可以參考下2018-11-11vue中如何使用echarts和echarts-gl實(shí)現(xiàn)3D餅圖環(huán)形餅圖
現(xiàn)在vue是很多公司前端的主流框架,我目前所在公司接觸的項(xiàng)目也都是使用vue來實(shí)現(xiàn)的,很少有完全使用原生的JavaScript來寫項(xiàng)目的了,下面這篇文章主要給大家介紹了關(guān)于vue中如何使用echarts和echarts-gl實(shí)現(xiàn)3D餅圖環(huán)形餅圖的相關(guān)資料,需要的朋友可以參考下2023-03-03vue中使用 pinia 全局狀態(tài)管理的實(shí)現(xiàn)
本文主要介紹了vue中使用 pinia 全局狀態(tài)管理的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07基于Vue的SPA動(dòng)態(tài)修改頁面title的方法(推薦)
這篇文章主要介紹了基于Vue的SPA動(dòng)態(tài)修改頁面title的方法,需要的朋友可以參考下2018-01-01