Vue3如何理解ref toRef和toRefs的區(qū)別
Vue3中新增了幾種創(chuàng)建響應(yīng)式數(shù)據(jù)的方法,其各自的作用當(dāng)然也不盡相同,每一種方法都有其自己的應(yīng)用場(chǎng)景,今天我們來(lái)聊聊什么是ref toRef和toRefs?三者在使用方式上有什么不同?最佳的使用方式是什么?
一、基礎(chǔ)
1.ref
(1) 生成值類(lèi)型的響應(yīng)式數(shù)據(jù), 通過(guò) .value修改值
<template> <div>{{ ageRef }}</div> </template> <script> import { ref } from 'vue' export default { setup() { const ageRef = ref(20) setInterval(() => { ageRef.value += 1 }, 1000) return { ageRef } }, } </script>
上面這段代碼,定義了一個(gè)ageRef變量,并每秒將ageRef加1,頁(yè)面展示的數(shù)值也會(huì)加1.
(2) 可用于reactive中
將上面的代碼改動(dòng)如下, 引入reactive定義變量,將ref定義的變量引入reactive中, 模板中展示reactive的變量. 最后的效果和上面(1)的一樣
<template> <div>{{ info.age }}</div> </template> <script> import { ref, reactive } from 'vue' export default { setup() { const ageRef = ref(20) const info = reactive({ age: ageRef }) setInterval(() => { ageRef.value += 1 }, 1000) return { info } }, } </script>
(3) 可用于獲取Dom
<template> <div ref="eleDom">ref-dom-test</div> </template> <script> import { ref, onMounted } from 'vue' export default { setup() { const eleDom = ref(null) onMounted(() => { console.log(eleDom.value.innerHTML) // ref-dom-test }) return { eleDom } }, }
上面代碼控制臺(tái)輸出ref-dom-test, 說(shuō)明獲取到了Dom元素.
要獲取Dom元素必須要符合以下規(guī)則
定義的ref變量名必須要和模板中ref中的值一致,如代碼中的eleDom
2.toRef
- 針對(duì)一個(gè)響應(yīng)式對(duì)象的prop
- 創(chuàng)建一個(gè)ref,具有響應(yīng)式
- 兩者保持引用關(guān)系
我們來(lái)看下面這段代碼
<template> <div>{{ state.age }} --- {{ ageRef }}</div> </template> <script> import { toRef, reactive } from 'vue' export default { setup() { const state = reactive({ name: 'JL', age: 18 }) const ageRef = toRef(state, 'age') setTimeout(() => { state.age = 20 }, 1000) setTimeout(() => { ageRef.value = 21 }, 2000) return { state, ageRef } }, } </script>
上面的代碼中,使用toRef將state的age屬性變成一個(gè)響應(yīng)式變量,然后在1秒后將state的age值變?yōu)?0,此時(shí)ageRef也會(huì)變成20;在2秒后將ageRef的值變?yōu)?1,此時(shí)state的age值也會(huì)變成21,說(shuō)明了兩者保持相互引用關(guān)系
toRef針對(duì)的是響應(yīng)式,針對(duì)的不是普通對(duì)象,如果用于非響應(yīng)式,產(chǎn)出的結(jié)果不具有響應(yīng)式
3.toRefs
- 將一個(gè)響應(yīng)式對(duì)象轉(zhuǎn)為普通對(duì)象
- 對(duì)象的每一個(gè)屬性都是對(duì)應(yīng)的ref
- 兩者保持引用關(guān)系
我們來(lái)看下面這段代碼
<template> <div>{{ name }}---{{ age }}</div> </template> <script> import { reactive, toRefs } from 'vue' export default { setup() { const state = reactive({ name: 'JL', age: 18 }) const stateRefs = toRefs(state) setTimeout(() => { state.age = 20 }, 1000) setTimeout(() => { stateRefs.age.value = 21 }, 2000) return stateRefs }, } </script>
上面的代碼中,使用toRefs將state轉(zhuǎn)變成一個(gè)普通對(duì)象,這時(shí)候就可以直接返回stateRefs,這時(shí)候在template就可以直接調(diào)用name和age。然后在1秒后將state的age值變?yōu)?0,此時(shí)頁(yè)面中的age也會(huì)變成20;在2秒后將stateRefs中的name的值變?yōu)?1,此時(shí)頁(yè)面中的age值也會(huì)變成21,說(shuō)明了兩者保持相互引用關(guān)系
toRefs將響應(yīng)式對(duì)象變成普通對(duì)象后,每一個(gè)屬性都具有響應(yīng)式ref,此時(shí)需要使用 .value才能獲取其值
4.最佳的使用方式
- reactive做對(duì)象的響應(yīng)式,ref做值類(lèi)型響應(yīng)式
- setup中返回toRefs(state), 或者toRef(state, 'xxx')---(這樣就能夠在template中不使用state.xxx)
- ref的變量命名都用xxxRef
- 合成函數(shù)返回響應(yīng)式對(duì)象時(shí),使用toRefs
例如:
<template> <div>x:{{x}} y:{{y}}</div> </template> <script> import { reactive, toRefs } from 'vue' export default { setup() { function test() { const state = reactive({ x: 1, y: 2 }) return toRefs(state) } const {x, y} = test() setTimeout(() => { x.value = 2 }, 1000) return { x, y } } } </script>
上面的代碼,test函數(shù)中定義了響應(yīng)式對(duì)象state,并通過(guò)toRefs將其轉(zhuǎn)為普通對(duì)象并返回,這時(shí)候可以結(jié)構(gòu)賦值,并且值是響應(yīng)式的
二、深入
1.為什么需要ref
在上面我們講到,使用reactive和toRef也可以將值類(lèi)型轉(zhuǎn)換成響應(yīng)式的,為什么還需要ref呢?
- 值類(lèi)型不具有響應(yīng)式(proxy)
- setup()、computed()...都可能返回值類(lèi)型,如果vue不定義ref,用戶需要響應(yīng)式的值類(lèi)型的時(shí)候就會(huì)通過(guò)其他方式(reactive/toRef, reactive/toRefs)自造ref,就會(huì)造成代碼更混亂
2.ref為什么需要.value
ref為什么需要加一個(gè).value來(lái)獲取值呢?為什么要這么麻煩呢?
- ref是一個(gè)對(duì)象(不會(huì)丟失響應(yīng)式),value存儲(chǔ)值
- 通過(guò).value屬性的get和set來(lái)實(shí)現(xiàn)響應(yīng)式
- 用于reactive和模板(vue編譯)的時(shí)候不需要.value,其他情況都需要
3.為什么需要toRef和toRefs
- 初衷: 在不丟失響應(yīng)式的前提下,對(duì)對(duì)象數(shù)據(jù)進(jìn)行解構(gòu)
- 前提: 針對(duì)的是響應(yīng)式對(duì)象,不是普通對(duì)象
- 結(jié)果: 不創(chuàng)造響應(yīng)式,只延續(xù)響應(yīng)式
到此這篇關(guān)于Vue3如何理解ref toRef和toRefs的區(qū)別的文章就介紹到這了,更多相關(guān)Vue3 ref toRef和toRefs內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中keep-alive多級(jí)路由緩存問(wèn)題
本文主要介紹了vue中keep-alive多級(jí)路由緩存問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12詳解Vue的鉤子函數(shù)(路由導(dǎo)航守衛(wèi)、keep-alive、生命周期鉤子)
這篇文章主要介紹了詳解Vue的鉤子函數(shù)(路由導(dǎo)航守衛(wèi)、keep-alive、生命周期鉤子),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07基于vue3實(shí)現(xiàn)一個(gè)抽獎(jiǎng)小項(xiàng)目
在公司年會(huì)期間我做了個(gè)抽獎(jiǎng)小項(xiàng)目,非常棒,今天把他分享到腳本之家平臺(tái),供大家學(xué)習(xí)參考,對(duì)vue3實(shí)現(xiàn)抽獎(jiǎng)小項(xiàng)目感興趣的朋友一起看看吧2023-01-013分鐘搞定vite項(xiàng)目(vue/react)使用vite-plugin-pwa配置為pwa應(yīng)用
這篇文章主要介紹了3分鐘搞定vite項(xiàng)目(vue/react)使用vite-plugin-pwa配置為pwa應(yīng)用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-02-02el-table表頭根據(jù)內(nèi)容自適應(yīng)完美解決表頭錯(cuò)位和固定列錯(cuò)位
這篇文章主要介紹了el-table表頭根據(jù)內(nèi)容自適應(yīng)完美解決表頭錯(cuò)位和固定列錯(cuò)位,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01vue2使用keep-alive緩存多層列表頁(yè)的方法
今天小編就為大家分享一篇vue2使用keep-alive緩存多層列表頁(yè)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09