Vue3中關(guān)于ref和reactive的問(wèn)題
關(guān)于ref和reactive的問(wèn)題
如果你使用過(guò) Vue3,你知道的,在 Vue3 中有兩個(gè)非常常用的響應(yīng)式 API:reactive 和 ref。它們會(huì)把我們想要追蹤的數(shù)據(jù)變成響應(yīng)式。
而且我們?cè)谑褂脮r(shí)一直被告知 ref 用于創(chuàng)建基礎(chǔ)類型的響應(yīng)式,也可以創(chuàng)建引用類型的響應(yīng)式。而對(duì)于引用類型,底層也是轉(zhuǎn)換為 reactive 來(lái)進(jìn)行響應(yīng)式處理。那既然這樣為撒還需要 reactive ,全部使用 ref 不就行了嗎?
雖然 ref 創(chuàng)建的響應(yīng)式數(shù)據(jù)在腳本中需要通過(guò) .value 才能訪問(wèn)到呀!但是這里肯定影響不大。并且在模板中會(huì)自動(dòng)添加上 .value,所以模板中不需要通過(guò) .value 訪問(wèn)。
既然這二者基本沒(méi)撒差別,但是還是暴露了 reactive 這個(gè) API,難道有什么場(chǎng)景是 reactive 能做而 ref 做不了的?
簡(jiǎn)單了解 ref & reactive
我們先簡(jiǎn)單了解一下這兩個(gè) API。
reactive
返回對(duì)象的響應(yīng)式副本,響應(yīng)式轉(zhuǎn)換是“深層”的——它影響所有嵌套 property。我們一般這樣寫(xiě)。
const obj = reactive({ count: 0 })并且可以直接使用。
const count = obj.count
ref
受一個(gè)內(nèi)部值并返回一個(gè)響應(yīng)式且可變的 ref 對(duì)象。ref 對(duì)象僅有一個(gè) .value property,指向該內(nèi)部值。我們一般是這樣寫(xiě)。
const data = ref(xxx)
引用的時(shí)候,一般會(huì)通過(guò)data.value的方式引用。
const dataValue = data.value
通過(guò)跟蹤 Vue3 的源代碼可以證明,當(dāng)我們調(diào)用 ref 方法來(lái)定義響應(yīng)式數(shù)據(jù)時(shí),當(dāng)參數(shù)為對(duì)象類型時(shí),其實(shí)里面用的是 reactive 方法。也就是說(shuō)上面的 data.value ,事實(shí)上是 reactive 方法創(chuàng)造出來(lái)的。
注意:
reactive 能做的 ref 也能做,并且還是用 reactive 做的
當(dāng) ref 的參數(shù)為對(duì)象時(shí),用的就是 reactive 方法
在 Vue3 中,如果是把對(duì)象類型的數(shù)據(jù)弄成響應(yīng)式,reactive 和 ref 都可以,且ref 內(nèi)部是通過(guò)r eactive 來(lái)支持的。也就是說(shuō),你 reactive 能做的,我 ref 也能做。
簡(jiǎn)單來(lái)說(shuō) ref 是在 reactive 上在進(jìn)行了封裝進(jìn)行了增強(qiáng),所以在 Vue3 中 reactive 能做的,ref 也能做,reactive 不能做的,ref 也能做。
個(gè)人理解ref是reactive的語(yǔ)法糖,如:ref(1) 就等價(jià)于 reactive({value: 1});
平時(shí)項(xiàng)目ref一把梭,是可以的,問(wèn)題也不大
vue3 ref 和reactive的區(qū)別
Ref
ref數(shù)據(jù)響應(yīng)式監(jiān)聽(tīng)。ref 函數(shù)傳入一個(gè)值作為參數(shù),一般傳入基本數(shù)據(jù)類型,返回一個(gè)基于該值的響應(yīng)式Ref對(duì)象,該對(duì)象中的值一旦被改變和訪問(wèn),都會(huì)被跟蹤到,就像我們改寫(xiě)后的示例代碼一樣,通過(guò)修改 count.value 的值,可以觸發(fā)模板的重新渲染,顯示最新的值
<template>
<h1>{{name}}</h1>
<h1>{{age}}</h1>
<button @click="sayName">按鈕</button>
</template>
<script lang="ts">
import {ref,computed} from 'vue'
export default {
name: 'App',
setup(){
const name = ref('zhangsan')
const birthYear = ref(2000)
const now = ref(2020)
const age = computed(()=>{
return now.value - birthYear.value
})
const sayName = () =>{
name.value = 'I am ' + name.value
}
return {
name,
sayName,
age
}
}
}
</script>
reactive
reactive是用來(lái)定義更加復(fù)雜的數(shù)據(jù)類型,但是定義后里面的變量取出來(lái)就不在是響應(yīng)式Ref對(duì)象數(shù)據(jù)了
所以需要用toRefs函數(shù)轉(zhuǎn)化為響應(yīng)式數(shù)據(jù)對(duì)象

將上面用ref寫(xiě)的代碼轉(zhuǎn)化成reactive型的代碼
<template>
<!-- <img alt="Vue logo" src="./assets/logo.png"> -->
<div>
<h1>{{ name }}</h1>
<h1>{{ age }}</h1>
<button @click="sayName">按鈕</button>
</div>
</template>
<script lang="ts">
import { computed, reactive,toRefs } from "vue";
interface DataProps {
name: string;
now: number;
birthYear: number;
age: number;
sayName: () => void;
}
export default {
name: "App",
setup() {
const data: DataProps = reactive({
name: "zhangsan",
birthYear: 2000,
now: 2020,
sayName: () => {
console.log(1111);
console.log(data.name);
data.name = "I am " + data.name;
console.log(data.name);
},
age: computed(() => {
return data.now - data.birthYear;
}),
});
const refData = toRefs(data)
refData.age
return {
...refData,
};
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
electron+vue?實(shí)現(xiàn)靜默打印功能
這篇文章主要介紹了electron+vue?實(shí)現(xiàn)靜默打印功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
vue2.0使用Sortable.js實(shí)現(xiàn)的拖拽功能示例
本篇文章主要介紹了vue2.0使用Sortable.js實(shí)現(xiàn)的拖拽功能示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02
Vue3 defineExpose要在方法聲明定義以后使用的教程
這篇文章主要介紹了Vue3 defineExpose要在方法聲明定義以后使用的教程,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02
vue3配置router路由并實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)功能
這篇文章主要介紹了vue3配置router路由并實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
vue3 與 vue2 優(yōu)點(diǎn)對(duì)比匯總
隨著用vue3 的開(kāi)發(fā)者越來(lái)越多,其必定是又她一定的有帶你,接下來(lái)這篇文章小編就為大家介紹vue3 對(duì)比 vue2 有什么優(yōu)點(diǎn)?感興趣的小伙伴請(qǐng)跟小編一起閱讀下文吧2021-09-09
詳解Vue路由History mode模式中頁(yè)面無(wú)法渲染的原因及解決
這篇文章主要介紹了詳解Vue路由History mode模式中頁(yè)面無(wú)法渲染的原因及解決,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09
關(guān)于vue?src路徑動(dòng)態(tài)拼接的小知識(shí)
這篇文章主要介紹了vue?src路徑動(dòng)態(tài)拼接的小知識(shí),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2022-04-04

