全面掌握Vue 3響應式:ref自動解包、reactive對象替換及響應式丟失問題

Vue 3的響應式系統是其最核心的特性之一,主要通過refreactive這兩個API來實現。本文將詳細介紹這兩個API的使用方法、區別以及最佳實踐。

1. ref()的基本使用

ref()用于創建一個響應式的數據引用。它可以包裝任何類型的值,包括基本類型和對象類型。

1.1 基本類型示例

import { ref } from 'vue'// 創建一個ref
const count = ref(0)// 訪問值
console.log(count.value) // 0// 修改值
count.value++
console.log(count.value) // 1// 在模板中使用(不需要.value)
<template><div>{{ count }}</div>
</template>

1.2 對象類型示例

import { ref } from 'vue'const user = ref({name: 'Alice',age: 25
})// 訪問和修改對象屬性
console.log(user.value.name) // 'Alice'
user.value.age = 26// 替換整個對象
user.value = {name: 'Bob',age: 30
}

2. reactive()的基本使用

reactive()用于創建一個響應式對象,但只能用于對象類型(包括數組和Map、Set等集合類型)。

reactive() 返回的是一個原始對象的 Proxy,它和原始對象是不相等的:

const raw = {}
const proxy = reactive(raw)// 代理對象和原始對象不是全等的
console.log(proxy === raw) // false

2.1 基本示例

import { reactive } from 'vue'const state = reactive({user: {name: 'Alice',age: 25},posts: []
})// 直接訪問和修改屬性(不需要.value)
console.log(state.user.name) // 'Alice'
state.user.age = 26
state.posts.push({ id: 1, title: 'Hello Vue 3' })

2.2 數組示例

const list = reactive([1, 2, 3])// 數組方法都會觸發響應式更新
list.push(4)
list.pop()
list[0] = 10

3. ref vs reactive的主要區別

  1. 使用方式

    • ref:需要通過.value訪問和修改值(模板中例外)
    • reactive:直接訪問和修改屬性
  2. 適用類型

    • ref:可以包裝任何類型
    • reactive:只能用于對象類型
    • ref 返回一個由 RefImpl 類構造出來的對象,而 reactive 返回一個原始對象的響應式代理 Proxy
  3. 嵌套轉換

// ref的嵌套對象轉換
const user = ref({name: 'Alice',info: { age: 25 }
})
// 結構:{ value: Proxy({ name: 'Alice', info: Proxy({ age: 25 }) }) }// reactive的嵌套對象轉換
const state = reactive({user: {name: 'Alice',info: { age: 25 }}
})
// 結構:Proxy({ user: { name: 'Alice', info: Proxy({ age: 25 }) } })

4. 注意事項

  1. 響應式丟失情況
import { reactive, toRefs } from 'vue';
const state = reactive({ count: 0 })// ? 錯誤用法:解構后失去響應性
const { count } = state// ? 正確用法:使用計算屬性
const count = computed(() => state.count)// ? 正確用法:使用toRefs
const { count } = toRefs(state); // 此時 count 仍然為響應式
  1. ref的自動解包
const count = ref(0)
const state = reactive({count // 在reactive對象中會自動解包
})console.log(state.count) // 直接訪問值,不需要.value
  1. 不能直接替換reactive對象
let state = reactive({ count: 0 })// 上面的 ({ count: 0 }) 引用將不再被追蹤
// (響應性連接已丟失!)
state = reactive({ count: 1 }) // 這將導致錯誤// ? 正確用法:修改屬性值
state.count = 1//? 正確用法:使用 Object.assign 合并對象
Object.assign(state, { count: 1, otherProp: 'value' })//? 正確用法:如果存在替換整個對象的需求,可以考慮使用 ref 代替 reactive:
const state = ref({ count: 0 })
state.value = { count: 1 }  // 合法操作
  1. 在模板中解包
//在模板渲染上下文中,只有頂級的 ref 屬性才會被解包。
//在下面的例子中,count 和 object 是頂級屬性,但 object.id 不是:
const count = ref(0)
const object = { id: ref(1) }<template>
{{ count + 1 }}
<!-- 但下面這個不會:-->
{{ object.id + 1 }}
</template>
//渲染的結果將是 [object Object]1,因為在計算表達式時 object.id 沒有被解包,仍然是一個 ref 對象。為了解決這個問題,我們可以將 id 解構為一個頂級屬性:
<template><!-- 在模板中自動解包 --><div>{{ count }}</div><!-- 在v-bind中也會自動解包 --><input :value="count"><!-- 但在事件處理器中需要.value --><button @click="count.value++">增加</button>
</template>

5. 總結

1. 核心特性對比

特性refreactive
數據類型任何類型僅對象類型
訪問方式.value(模板中自動解包)直接訪問
實現方式RefImpl類Proxy
解構行為保持響應性失去響應性
對象處理內部使用reactive直接代理

2. 最佳實踐要點

  1. 類型選擇

    • 基本類型使用ref()
    • 復雜對象使用reactive()
    • 官方建議使用 ref() 作為聲明響應式狀態的主要 API
  2. 避免常見陷阱

    • 不要解構reactive對象
    • 不要直接替換reactive對象
    • 注意在事件處理器中使用ref需要.value
  3. 性能優化

    • 合理使用shallowRefshallowReactive
    • 避免不必要的深層響應式轉換
    • 大型數據集合考慮使用shallowRef

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86511.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86511.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86511.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【科普】 AI大模型應用架構圖大全

AI大模型應用架構圖大全 AI大模型技術全景視圖&#xff1a; AI大模型通用技術架構圖 AI大模型通用技術架構圖 AI大模型通用技術架構圖 RAG知識庫業務架構圖 AI農業大模型技術架構圖 AI導購大模型技術架構圖 AI導購大模型技術架構圖 AI大模型合規風控管理架構圖 AI大模型合規管…

Educational Codeforces Round 180 (Rated for Div. 2) A-D題解

A. Race 題意 在一個數軸上&#xff0c;獎品可能出現在 x x x 點或 y y y 點&#xff0c;Alice 現在在 a a a 點&#xff0c;請問Bob是否存在一個點 b b b&#xff0c;使得無論獎品出現在 x x x 點還是 y y y 點&#xff0c;Bob都能比Alice先拿到&#xff08; ∣ b ?…

IPv6配置

IPv6的基本配置 構建如下圖所示的實訓拓撲&#xff0c;按如下要求完成實訓內容&#xff1a; &#xff08;1&#xff09;啟用路由器的IPv6功能&#xff1b; &#xff08;2&#xff09;配置路由器接口的IPv6地址&#xff1b; &#xff08;3&#xff09;測試兩臺路由器的連通性…

flutter項目環境升級二:從Flutter2.10.5升級到3.29.3

系統:windows Android Studio:Android Studio Meerkat Feature Drop | 2024.3.2 Patch 1 Flutter SDK: Flutter3.29.3 JDK: java 17 詳細的AGP / Gradle / Kotlin / JDK版本兼容關系可以百度或者到官方文檔查詢,其他博主給的很詳細。確認好想要的版本兼容 這位大哥有對照表…

【網站內容安全檢測】之1:獲取網站所有鏈接sitemap數據

不多BB&#xff0c;直接上代碼&#xff1a; main.go package mainimport ("bufio""crypto/tls""fmt""io""net/http""net/url""os""strings""sync""time"_ "net/ht…

從零構建vue3項目(二)

Vue3項目增強配置&#xff1a;Axios封裝、鑒權與代碼掃描 1. Axios二次封裝與攔截器配置 安裝Axios npm install axios創建Axios實例 src/utils/request.js import axios from axios import { useUserStore } from /stores/user import router from /router// 創建axios實例…

哪家香港站群服務器比較好用?

面對魚龍混雜的服務商市場&#xff0c;哪家的香港站群服務器真正穩定&#xff1f;畢竟搞站群最怕的就是服務器抽風&#xff0c;輕則掉排名&#xff0c;重則客戶跑光光。今天咱就重點聊聊哪家香港站群服務器比較好用&#xff1f; 一般來說&#xff0c;在選擇香港站群服務器提供…

Python的科學計算庫NumPy(二)

5. 索引和切片 5.1 一維數組的索引和切片 import numpy as np# 一維數組索引和切片&#xff0c;跟python中的集合同樣使用 bin_list[1,2,3,4,5,6] bin_arraynp.array(bin_list) print(bin_array[3]) print(bin_array[1:4]) print(bin_array[-2:-1])5.2 多維數組的索引 # 多維…

STM32和C++ 實現配置文件導入、導出功能

一.配置文件導出功能 // 導出流程 // 1. 客戶端 → 設備:導出配置請求,例如:GetFlashData[d6fe30323454]:{ini} ,其中[]里面是設備序列號 // 2. 設備 → 客戶端:配置文件元數據(總大小、塊數量) // 3. 設備 → 客戶端:發送塊1(包含塊序號和大小) // 4. 設備 → 客戶端:…

HTTP 請求基礎知識

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言HTTP 請求方法GETPOSTPUTDELETE其他方法 HTTP 請求結構常用請求頭實際應用示例響應狀態碼 前言 HTTP (Hypertext Transfer Protocol) 是互聯網上應用最廣泛的協…

Django ORM 1. 創建模型(Model)

1. ORM介紹 什么是ORM&#xff1f; ORM&#xff0c;全稱 Object-Relational Mapping&#xff08;對象關系映射&#xff09;&#xff0c;一種通過對象操作數據庫的技術。 它的核心思想是&#xff1a;我們不直接寫 SQL&#xff0c;而是用 Python 對象&#xff08;類/實例&…

【C/C++】C++ 編程規范:101條規則準則與最佳實踐

C 編程規范&#xff1a;101條規則準則與最佳實踐 引言 C 是一門強大而復雜的語言&#xff0c;能高效控制硬件&#xff0c;也能寫出優雅抽象。然而&#xff0c;正因其復雜性&#xff0c;項目中若缺乏統一規范&#xff0c;極易陷入混亂、難維護、易出錯的泥潭。 本文總結了 10…

柔性屏激光修屏禁區突破:新啟航如何實現曲面 OLED 面板的無損修復?

一、引言 柔性 OLED 面板憑借其輕薄、可彎曲等特性&#xff0c;在智能終端、可穿戴設備等領域廣泛應用。然而&#xff0c;生產過程中面板易出現缺陷&#xff0c;傳統修復方法難以滿足曲面 OLED 面板的無損修復需求。新啟航半導體有限公司在激光修屏技術上取得突破&#xff0c;…

UI前端與數字孿生結合案例分享:智慧零售的可視化解決方案

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩! 一、引言&#xff1a;智慧零售的可視化變革 在數字化浪潮下&#xff0c;零售行業正從 “人貨場…

Docker 入門教程(四):容器命令

文章目錄 &#x1f433; Docker 入門教程&#xff08;四&#xff09;&#xff1a;容器命令創建并運行容器&#xff1a;docker run查看容器列表&#xff1a;docker ps停止、啟動、重啟容器刪除容器&#xff1a;docker rm進入容器&#xff1a;exec 和 attach查看容器日志&#xf…

2025.06.27【技術觀察L0】AlphaGenome:DeepMind推出的全新AI基因組解讀平臺

AlphaGenome&#xff1a;DeepMind推出的全新AI基因組解讀平臺詳解 2025年6月&#xff0c;Google DeepMind團隊正式發布了AlphaGenome——一款面向基因組功能解讀和變異效應預測的全新人工智能模型。AlphaGenome的出現&#xff0c;標志著AI在基因組學領域邁出了重要一步&#x…

[ARM-2D 專題]7. OOP實現之繼承,宏implement_ex的實現和解析

implement_ex宏是 Arm-2D 庫中用于面向對象編程&#xff08;OOP&#xff09;支持的核心宏定義。 implement_ex 宏的定義和作用 implement_ex 宏在 Library/Include/arm_2d_utils.h 中定義&#xff0c;用于在 C 語言中實現類似繼承的功能&#xff1a; /*!* \note do NOT use t…

默認構造函數

1、構造函數 一、什么是構造函數 c中有一種特殊的成員函數&#xff0c;他的名字和類名相同&#xff0c;沒有返回值&#xff0c;而在創建對象時會自動執行&#xff0c;類中的數據成員的初始化往往通過構造函數來實現。完成類中數據成員的初始化&#xff0c;同時也是類中的成員…

帶標簽的 Docker 鏡像打包為 tar 文件

現在還有人用docker嗎 要將帶標簽的 Docker 鏡像打包為 tar 文件&#xff0c;請使用 docker save 命令。以下是詳細操作指南&#xff1a; 一、單鏡像打包&#xff08;推薦方式&#xff09; # 基礎格式 docker save -o [輸出文件名].tar [鏡像名]:[標簽]# 示例&#xff1a;將…

基于GPS-RTK的履帶吊車跑偏檢測技術方案

基于GPS-RTK的履帶吊車跑偏檢測技術方案 1. 引言 1.1 項目背景 履帶吊車作為重型工程機械&#xff0c;其行駛穩定性直接關系到作業安全和設備壽命。跑偏現象會導致履帶異常磨損、轉向系統過載&#xff0c;嚴重時可能引發側翻事故。傳統檢測方法&#xff08;如激光測距或人工觀…