Vue3中ref和reactive的使用場景詳解
Vue3中ref和reactive的使用場景
一、核心區(qū)別
特性 | ref | reactive |
---|---|---|
數(shù)據(jù)類型 | 基本類型 + 對象/數(shù)組(自動解包) | 僅對象/數(shù)組 |
響應(yīng)式原理 | 通過 .value 觸發(fā)響應(yīng) | 直接代理對象 |
模板中使用 | 自動解包(無需 .value) | 直接訪問屬性 |
解構(gòu)/傳遞 | 保持響應(yīng)性 | 需用 toRefs 保持響應(yīng)性 |
二、使用場景與案例
1. ref 的典型場景
(1) 管理基本類型值
import { ref } from 'vue' // 計數(shù)器(數(shù)字) const count = ref(0) const increment = () => { count.value++ // 修改值必須用 .value } // 開關(guān)狀態(tài)(布爾值) const isOpen = ref(false) const toggle = () => { isOpen.value = !isOpen.value }
(2) 引用 DOM 元素
<template> <input ref="inputRef" /> </template> <script setup> import { ref, onMounted } from 'vue' const inputRef = ref(null) onMounted(() => { inputRef.value.focus() // 訪問 DOM 元素 }) </script>
(3) 需要整體替換對象/數(shù)組
const user = ref({ name: 'Alice', age: 25 }) // 替換整個對象 user.value = { name: 'Bob', age: 30 } const list = ref(['apple', 'banana']) // 替換整個數(shù)組 list.value = ['orange', 'grape']
2. reactive 的典型場景
(1) 復(fù)雜表單對象
import { reactive } from 'vue' const form = reactive({ username: '', password: '', rememberMe: false }) // 直接修改屬性(無需 .value) form.username = 'John'
(2) 嵌套數(shù)據(jù)結(jié)構(gòu)
const nestedData = reactive({ user: { profile: { name: 'Alice', address: { city: 'Shanghai' } } } }) // 深層嵌套修改仍保持響應(yīng)性 nestedData.user.profile.address.city = 'Beijing'
(3) 數(shù)組操作
const items = reactive(['a', 'b', 'c']) // 直接修改元素 items[0] = 'z' // 響應(yīng)式更新 items.push('d') // 使用數(shù)組方法
三、關(guān)鍵操作指南
1. 正確賦值/修改
ref 示例:
const count = ref(0) // ? 正確修改 count.value = 10 // ? 錯誤!直接賦值會覆蓋 ref 對象 count = 10
reactive 示例:
const state = reactive({ count: 0 }) // ? 正確修改屬性 state.count = 10 // ? 錯誤!直接替換對象會失去響應(yīng)性 state = { count: 20 } // ? 保持響應(yīng)性的對象替換方式 Object.assign(state, { count: 20 })
2. 處理響應(yīng)式丟失
(1) 解構(gòu) reactive 對象
const state = reactive({ x: 1, y: 2 }) // ? 解構(gòu)后失去響應(yīng)性 const { x, y } = state // ? 使用 toRefs 保持響應(yīng)性 const { x, y } = toRefs(state) x.value = 10 // 現(xiàn)在修改有效
(2) 函數(shù)間傳遞
// ? 傳遞整個 reactive 對象 const user = reactive({ name: 'Alice' }) updateUser(user) function updateUser(userObj) { userObj.name = 'Bob' // 修改仍響應(yīng) } // ? 傳遞 ref 對象 const count = ref(0) increment(count) function increment(numRef) { numRef.value++ }
四、性能與最佳實踐
優(yōu)先選擇:
- 基本類型 →
ref
- 復(fù)雜對象 →
reactive
- 需要靈活替換 →
ref
(即使存儲對象)
注意事項:
- 避免在
reactive
中嵌套ref
(除非明確需要) - 對數(shù)組進(jìn)行索引操作時,建議使用變更方法(
push/pop
等) - 大型數(shù)據(jù)集考慮
shallowRef
/shallowReactive
提升性能
五、綜合對比案例
<script setup> import { ref, reactive } from 'vue' // ref 管理用戶ID(基本類型) const userId = ref(123) // reactive 管理用戶詳情(對象) const userDetail = reactive({ name: 'Alice', permissions: ['read', 'write'] }) // 修改操作示例 const updateUser = () => { // 修改 ref userId.value = 456 // 修改 reactive 對象 userDetail.name = 'Bob' userDetail.permissions.push('delete') } // 替換整個對象的最佳實踐 const resetUser = () => { // ref 可以直接替換 userId.value = 0 // reactive 應(yīng)該合并屬性而非直接賦值 Object.assign(userDetail, { name: 'Guest', permissions: [] }) } </script>
通過以上案例可以看出:ref
更適合管理獨立值和需要完全替換的場景,而 reactive
在處理復(fù)雜對象結(jié)構(gòu)時更直觀。根據(jù)具體需求靈活選擇,可顯著提升代碼可維護(hù)性。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue 路由緩存 路由嵌套 路由守衛(wèi) 監(jiān)聽物理返回操作
這篇文章主要介紹了vue 路由緩存 路由嵌套 路由守衛(wèi) 監(jiān)聽物理返回操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08vue3第二次傳遞數(shù)據(jù)方法無法獲取到最新的值的解決方法
這篇文章主要介紹了vue3第二次傳遞數(shù)據(jù)方法無法獲取到最新的值,本文通過實例圖文相結(jié)合給大家詳細(xì)講解,感興趣的朋友一起看看吧2025-04-04