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