詳解Vue3中ref和reactive函數(shù)的使用
前言
上一篇博文介紹 setup 函數(shù)的時(shí)候,最后出現(xiàn)一個(gè)問(wèn)題,就是在 setup 函數(shù)中,編寫(xiě)一個(gè)事件,直接去修改定義的變量,發(fā)現(xiàn)頁(yè)面上沒(méi)有更新成功,并且控制臺(tái)報(bào)錯(cuò),那這篇博客就是講解遇到的這個(gè)問(wèn)題應(yīng)該如何處理。
ref 函數(shù)介紹
- ref 作用就是將基礎(chǔ)數(shù)據(jù)轉(zhuǎn)換為響應(yīng)式數(shù)據(jù),把數(shù)據(jù)包裝成響應(yīng)式的引用數(shù)據(jù)類型的數(shù)據(jù)。
- 通過(guò)對(duì)參數(shù)返回值的 value 屬性獲取響應(yīng)式的值,并且修改的時(shí)候也需要對(duì) value 進(jìn)行修改。
- 在 vue2 當(dāng)中,通過(guò)給元素添加 ref='xxx' ,然后使用 refs.xxx 的方式來(lái)獲取元素,vue3 也可以。
- 當(dāng) ref 里面的值發(fā)生變化的時(shí)候,視圖會(huì)自動(dòng)更新數(shù)據(jù)。
- ref 可以操作基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型,建議使用 ref 操作只對(duì)基本數(shù)據(jù)類型進(jìn)行操作。
ref 函數(shù)使用
使用 ref 函數(shù)很簡(jiǎn)單,首先要在頁(yè)面引用,然后就可以直接使用了,具體怎么使用呢,下面為了方便介紹,簡(jiǎn)單來(lái)幾個(gè)案例。
ref 函數(shù)處理基本數(shù)據(jù)類型
首先提一個(gè)需求:頁(yè)面有一個(gè)名稱需要顯示,有一個(gè)按鈕,點(diǎn)擊按鈕的時(shí)候修改頁(yè)面展示的這個(gè)名字。
<template>
<div>
<h1>ref reactive 函數(shù)</h1>
<h1>姓名:{{name_ref}}</h1>
<el-button type="primary" @click="btn">修改名字</el-button>
</div>
</template>
<script>
import { ref } from 'vue' // 引入 ref
export default {
setup() {
const name = '????.' // 創(chuàng)建一個(gè)變量為 ????.
const name_ref = ref(name) // ref 將參數(shù)包裹轉(zhuǎn)換成響應(yīng)式數(shù)據(jù)
const btn = () => { // 按鈕點(diǎn)擊修改名字
name_ref = '我是????.' // 將名字內(nèi)容改為 我是????.
}
return { name_ref, btn } // 把頁(yè)面需要使用的參數(shù)和方法拋出去
}
}
</script>
編寫(xiě)完上面的代碼保存刷新,可以正常渲染數(shù)據(jù),但是點(diǎn)擊按鈕修改名字的時(shí)候,出現(xiàn)問(wèn)題!

為什么使用過(guò) ref 將數(shù)據(jù)映射為響應(yīng)式數(shù)據(jù)還是報(bào)錯(cuò)呢?我們可以先打印一下 ref 包裹后,也就是 name_ref 這個(gè)參數(shù),看一下他的結(jié)構(gòu)。

所以說(shuō)修改代碼:
<template>
<div>
<h1>ref reactive 函數(shù)</h1>
<h1>姓名:{{name_ref}}</h1>
<el-button type="primary" @click="btn">修改名字</el-button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const name = '????.'
const name_ref = ref(name)
console.log(name_ref)
const btn = () => {
name_ref.value = '我是????.' // 對(duì)響應(yīng)式數(shù)據(jù)的value進(jìn)行操作
}
return { name_ref, btn }
}
}
</script>
然后在保存代碼刷新頁(yè)面查看效果。

非常棒,數(shù)據(jù)完美的修改了。
有一點(diǎn)需要說(shuō)一下哈,就是在單文件組件中,不必寫(xiě)value,因?yàn)閟etup方法會(huì)自動(dòng)解析,簡(jiǎn)單的可以理解成 html 代碼不需要額外操作 value,但是邏輯層需要。
ref 函數(shù)處理復(fù)雜數(shù)據(jù)類型
首先聲明:不建議使用 ref 函數(shù)處理復(fù)雜數(shù)據(jù)類型(數(shù)組、對(duì)象等),用 ref 函數(shù)處理基本數(shù)據(jù)類型(數(shù)字、字符串等)就可以了。
例如我們寫(xiě)一個(gè)案例,創(chuàng)建一個(gè)個(gè)人信息,放到對(duì)象里面展示。
<template>
<div>
<h1>ref reactive 函數(shù)</h1>
<h1>姓名:{{name_ref.name}}</h1>
<h1>年齡:{{name_ref.age}}</h1>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const boy = {
name: '????.',
age: 10
}
const name_ref = ref(boy)
console.log(name_ref)
return { name_ref }
}
}
</script>
我們先看一下對(duì)象被 ref 函數(shù)包裹后的數(shù)據(jù)結(jié)構(gòu)。

所以說(shuō),對(duì)象而言,我們修改也是通過(guò) value 進(jìn)行操作。
<template>
<div>
<h1>ref reactive 函數(shù)</h1>
<h1>姓名:{{name_ref.name}}</h1>
<h1>年齡:{{name_ref.age}}</h1>
<el-button type="primary" @click="btn">修改名字</el-button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const boy = {
name: '????.',
age: 10
}
const name_ref = ref(boy)
console.log(name_ref)
const btn = () => {
name_ref.value.name = '我是????.' // 對(duì)響應(yīng)式數(shù)據(jù)的value進(jìn)行操作
name_ref.value.age = 11 // 對(duì)響應(yīng)式數(shù)據(jù)的value進(jìn)行操作
}
return { name_ref, btn }
}
}
</script>
保存代碼,刷新頁(yè)面,查看效果。

看到名稱和年齡都被成功修改了。
當(dāng)然了,對(duì)于數(shù)組的操作也是一樣的啦!
<template>
<div>
<h1>ref reactive 函數(shù)</h1>
<h1>姓名:{{name_ref[0]}}</h1>
<h1>年齡:{{name_ref[1]}}</h1>
<el-button type="primary" @click="btn">修改名字</el-button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const boy = ['????.', 10]
const name_ref = ref(boy)
const btn = () => {
name_ref.value[0] = '我是????.' // 對(duì)響應(yīng)式數(shù)據(jù)的value進(jìn)行操作
name_ref.value[1] = 11 // 對(duì)響應(yīng)式數(shù)據(jù)的value進(jìn)行操作
}
return { name_ref, btn }
}
}
</script>
保存查看,一樣的效果。

ref 函數(shù)獲取單個(gè)DOM元素
和 vue2 一樣,可以使用 ref 獲取元素,用法和操作數(shù)據(jù)類型相似。
頁(yè)面上有一個(gè)標(biāo)簽,點(diǎn)擊按鈕,獲取標(biāo)簽的相關(guān)數(shù)據(jù)。
<template>
<div>
<h1>ref reactive 函數(shù)</h1>
<p style="color: blue;" ref="boy">我是????.</p>
<el-button type="primary" @click="btn">獲取元素</el-button>
</div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
setup() {
let boy = ref();
const btn = () => {
console.log(boy)
console.log(boy.value)
console.log(boy.value.innerText)
console.log(boy.value.style.color)
}
return {boy, btn }
}
}
</script>
刷新查看運(yùn)行效果。

其他相關(guān)方法
isRef
判斷是否為 ref 對(duì)象。
<script>
import { ref, isRef } from 'vue'
export default {
setup() {
const a = ref('a')
const b = 'b'
console.log(isRef(a)) // true
console.log(isRef(b)) // false
}
}
</script>

unref
如果參數(shù)為 ref,則返回內(nèi)部值,否則返回參數(shù)本身。
val = isRef(val) ? val.value : val
上邊代碼可以看懂吧?
<script>
import { ref, unref } from 'vue'
export default {
setup() {
const temp = ref(3)
const newTemp = unref(temp) // newTemp 確?,F(xiàn)在是數(shù)字類型 3
const a = unref(1) // a 確?,F(xiàn)在是數(shù)字類型 1
console.log(newTemp, a)
}
}
</script>

好了,這是 ref 函數(shù)和與其常見(jiàn)的相關(guān)的其他函數(shù)相關(guān)的知識(shí)點(diǎn)內(nèi)容,到此為止吧,有其他的可以自己在研究一下。
reactive 函數(shù)介紹
上面說(shuō)了 ref 函數(shù)的基本用法,接下來(lái)是 reactive 函數(shù),它的用法與 ref 函數(shù)的用法相似,也是將數(shù)據(jù)變成響應(yīng)式數(shù)據(jù),當(dāng)數(shù)據(jù)發(fā)生變化時(shí)UI也會(huì)自動(dòng)更新。不同的是 ref 用于基本數(shù)據(jù)類型,而 reactive 是用于復(fù)雜數(shù)據(jù)類型,所以說(shuō),不建議用 ref 函數(shù)來(lái)處理復(fù)雜數(shù)據(jù)類型的原因就是,有 reactive 來(lái)處理復(fù)雜類型數(shù)據(jù)。
reactive 函數(shù)使用
用完了 ref 函數(shù),那 reactive 函數(shù)就很好理解了哈。
ref 函數(shù)處理對(duì)象
還是, reactive 函數(shù)用來(lái)處理數(shù)組或者是對(duì)象,我們還是寫(xiě)一個(gè)案例,操作人的基本信息。
我們還是先打印一下用 reactive 函數(shù)包裹后的數(shù)據(jù)結(jié)構(gòu)。
<template>
<div>
<h1>ref reactive 函數(shù)</h1>
<p>姓名:{{boy_reactive.name}}</p>
<p>年齡:{{boy_reactive.age}}</p>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup() {
const boy = {
name: '我是????.',
age: 10
}
const boy_reactive = reactive(boy)
console.log(boy_reactive)
return { boy_reactive }
}
}
</script>

有打印的結(jié)果我們可以看見(jiàn),這時(shí)候的數(shù)據(jù)就不是被包裹在 value 下面了,所以說(shuō)我們可以直接獲取到。
<template>
<div>
<h1>ref reactive 函數(shù)</h1>
<p>姓名:{{boy_reactive.name}}</p>
<p>年齡:{{boy_reactive.age}}</p>
<el-button type="primary" @click="btn">修改信息</el-button>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup() {
const boy = {
name: '我是????.',
age: 10
}
const boy_reactive = reactive(boy)
const btn = () => {
boy_reactive.name = '????.'
boy_reactive.age = 11
}
return { boy_reactive, btn }
}
}
</script>
保存刷新,查看效果。

ref 函數(shù)處理數(shù)組
處理數(shù)組的方式和處理對(duì)象的方式是一樣一樣的。
直接上代碼:
<template>
<div>
<h1>ref reactive 函數(shù)</h1>
<p>姓名:{{boy_reactive[0]}}</p>
<p>年齡:{{boy_reactive[1]}}</p>
<el-button type="primary" @click="btn">修改信息</el-button>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup() {
const boy = ['我是????.', 10]
const boy_reactive = reactive(boy)
const btn = () => {
boy_reactive[0] = '????.'
boy_reactive[1] = 11
}
return { boy_reactive, btn }
}
}
</script>

我們可以看到效果是一樣的。
以上就是詳解Vue3中ref和reactive函數(shù)的使用的詳細(xì)內(nèi)容,更多關(guān)于Vue3 ref reactive的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
前端+接口請(qǐng)求實(shí)現(xiàn)vue動(dòng)態(tài)路由
在Vue應(yīng)用中,結(jié)合前端和后端接口請(qǐng)求實(shí)現(xiàn)動(dòng)態(tài)路由,可根據(jù)用戶權(quán)限動(dòng)態(tài)生成路由,提高安全性與靈活性,本文就來(lái)介紹一下前端+接口請(qǐng)求實(shí)現(xiàn)vue動(dòng)態(tài)路由,感興趣的可以了解一下2024-09-09
解決基于 keep-alive 的后臺(tái)多級(jí)路由緩存問(wèn)題
這篇文章主要介紹了解決基于 keep-alive 的后臺(tái)多級(jí)路由緩存問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
vue管理系統(tǒng)項(xiàng)目中的一些核心技能匯總
Vue是當(dāng)今增長(zhǎng)最快的前端框架,Vue 平易近人、用途廣泛且性能卓越,它的語(yǔ)法非常直觀,并且具有友好的學(xué)習(xí)曲線,是開(kāi)發(fā)人員最想學(xué)習(xí)的頂級(jí)前端庫(kù)之一,下面這篇文章主要給大家介紹了關(guān)于vue管理系統(tǒng)項(xiàng)目中的一些核心技能,需要的朋友可以參考下2022-05-05
安裝node.js以及搭建vue項(xiàng)目過(guò)程中遇到的問(wèn)題詳解
為了讓一些不太清楚搭建前端項(xiàng)目的小白,更快上手,下面這篇文章主要給大家介紹了關(guān)于安裝node.js以及搭建vue項(xiàng)目過(guò)程中遇到問(wèn)題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
Vue全局使用less樣式,組件使用全局樣式文件中定義的變量操作
這篇文章主要介紹了Vue全局使用less樣式,組件使用全局樣式文件中定義的變量操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
寫(xiě)給新手同學(xué)的vuex快速上手指北小結(jié)
這篇文章主要介紹了寫(xiě)給新手同學(xué)的vuex快速上手指北小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
vue.js入門(mén)教程之綁定class和style樣式
小編之前介紹了通過(guò)vue.js計(jì)算屬性,不知道大家都學(xué)會(huì)了嗎。那這篇文章中我們將一起學(xué)習(xí)vue.js實(shí)現(xiàn)綁定class和style樣式,有需要的朋友們可以參考借鑒。2016-09-09

