vue中ref()和reactive()區(qū)別小結(jié)
好的,這是 Vue 3 中 ref()
和 reactive()
這兩個(gè)核心響應(yīng)式 API 之間區(qū)別的詳細(xì)解釋。
簡(jiǎn)單來(lái)說(shuō),它們是創(chuàng)建響應(yīng)式數(shù)據(jù)的兩種方式,主要區(qū)別在于處理的數(shù)據(jù)類型和訪問(wèn)數(shù)據(jù)的方式。
核心區(qū)別速查表
特性 | ref() | reactive() |
---|---|---|
適用類型 | ? 任何類型 (字符串、數(shù)字、布爾、對(duì)象、數(shù)組等) | ? 僅限對(duì)象類型 (Object, Array, Map, Set) |
訪問(wèn)/修改 | 在 JS 中必須通過(guò) .value 屬性 | 在 JS 中直接訪問(wèn),像普通對(duì)象一樣 |
模板中使用 | 不需要 .value,Vue 會(huì)自動(dòng)解包 | 直接訪問(wèn),像普通對(duì)象一樣 |
重新賦值 | ? 可以對(duì)整個(gè) .value 重新賦值 | ? 不能直接對(duì)整個(gè)變量重新賦值,會(huì)破壞響應(yīng)性 |
底層原理 | 通過(guò)一個(gè)包含 value 屬性的對(duì)象來(lái)實(shí)現(xiàn)包裝 | 使用 ES6 的 Proxy 實(shí)現(xiàn)對(duì)整個(gè)對(duì)象的劫持 |
ref():更靈活的“盒子”
ref()
的設(shè)計(jì)初衷是為了處理原始數(shù)據(jù)類型(Primitive Types),如字符串、數(shù)字、布爾值。當(dāng)然,它也可以用來(lái)包裝對(duì)象。
你可以把 ref()
想象成一個(gè)萬(wàn)能的、響應(yīng)式的“盒子”。無(wú)論你放什么進(jìn)去,它都會(huì)把它裝進(jìn)一個(gè)特殊的盒子里。要訪問(wèn)或修改里面的東西,你需要打開(kāi)這個(gè)盒子,也就是訪問(wèn)它的 .value
屬性。
ref()的關(guān)鍵點(diǎn):
- 接受任何值:ref('some string'), ref(123), ref(true), ref({ name: '張三' }) 都可以。
- JS 中必須用 .value:在 <script setup> 或 setup() 函數(shù)中,訪問(wèn)和修改 ref 創(chuàng)建的變量時(shí),必須通過(guò) .value。
- 模板中自動(dòng)解包:在 <template> 中使用時(shí),Vue 非常智能,會(huì)自動(dòng)“打開(kāi)盒子”,所以你不需要寫(xiě) .value。
ref()示例代碼:
<template> <div> <p>計(jì)數(shù): {{ count }}</p> <button @click="increment">增加</button> <p>用戶信息: {{ user.name }}</p> </div> </template> <script setup> import { ref } from 'vue'; // 1. 用于原始類型 const count = ref(0); // 2. 在 JS/TS 中,必須通過(guò) .value 來(lái)訪問(wèn)和修改 function increment() { count.value++; } // 3. 也可以用于對(duì)象,但同樣需要 .value const user = ref({ name: '張三' }); console.log(user.value.name); // 輸出: 張三 </script>
reactive():對(duì)象的“代理”
reactive()
專門(mén)用于將對(duì)象類型(包括普通對(duì)象、數(shù)組、Map、Set)的數(shù)據(jù)轉(zhuǎn)換成響應(yīng)式數(shù)據(jù)。
它不做任何包裝,而是直接返回一個(gè)原始對(duì)象的“代理” (Proxy)。你對(duì)這個(gè)代理對(duì)象的所有操作(讀取、修改、添加、刪除屬性)都會(huì)被 Vue 攔截,從而觸發(fā)視圖更新。
reactive()的關(guān)鍵點(diǎn):
- 只能用于對(duì)象:reactive({ ... }), reactive([ ... ]) 可以,但 reactive(123) 會(huì)報(bào)錯(cuò)。
- 直接訪問(wèn):使用起來(lái)和普通 JS 對(duì)象一模一樣,不需要 .value。
- 不能重新賦值:這是一個(gè)非常重要的陷阱!你不能直接用一個(gè)新的對(duì)象替換整個(gè) reactive 變量,否則會(huì)失去響應(yīng)性,因?yàn)檫@切斷了原始代理對(duì)象的連接。
reactive()示例代碼:
<template> <div> <p>用戶信息: {{ state.user.name }} - {{ state.user.age }} 歲</p> <p>他的愛(ài)好: {{ state.hobbies.join('、') }}</p> <button @click="updateUser">更新用戶信息</button> </div> </template> <script setup> import { reactive } from 'vue'; // 1. 只能用于對(duì)象或數(shù)組 const state = reactive({ user: { name: '李四', age: 30 }, hobbies: ['編程', '音樂(lè)'] }); function updateUser() { // 2. 直接修改屬性,像普通對(duì)象一樣 state.user.age++; state.hobbies.push('運(yùn)動(dòng)'); // ? 錯(cuò)誤做法:直接替換整個(gè)對(duì)象會(huì)導(dǎo)致響應(yīng)性丟失! // state = { user: { name: '王五', age: 40 }, hobbies: [] }; // ? 正確做法:逐個(gè)屬性賦值或使用 Object.assign // Object.assign(state, { user: { name: '王五', age: 40 }, hobbies: [] }); } </script>
總結(jié)與使用建議
優(yōu)先使用 ref():
- 當(dāng)你需要處理原始數(shù)據(jù)類型(字符串、數(shù)字、布爾值)時(shí),必須使用 ref()。
- 當(dāng)你不確定數(shù)據(jù)類型時(shí),ref() 是更安全、更通用的選擇。
- 社區(qū)中有一種流行的風(fēng)格是“始終使用 ref()”,以保持代碼風(fēng)格的一致性。因?yàn)?ref() 既能處理原始類型,也能處理對(duì)象。
在特定場(chǎng)景下使用 reactive():
- 當(dāng)你明確知道你需要一個(gè)復(fù)雜的、多層級(jí)的響應(yīng)式對(duì)象或數(shù)組時(shí),使用 reactive() 可以讓代碼更簡(jiǎn)潔,因?yàn)槟悴恍枰教帉?xiě) .value。例如,管理一個(gè)復(fù)雜的表單狀態(tài)。
一個(gè)簡(jiǎn)單的記憶法則:
- ref -> 凡事用它準(zhǔn)沒(méi)錯(cuò),就是記得在 JS 里加 .value。
- reactive -> 專為對(duì)象服務(wù),用法自然,但小心別整個(gè)替換掉它。
到此這篇關(guān)于vue中ref()和reactive()區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)vue ref()和reactive()區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何測(cè)量vue應(yīng)用運(yùn)行時(shí)的性能
這篇文章主要介紹了如何測(cè)量vue應(yīng)用運(yùn)行時(shí)的性能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下2019-06-06在?Vue?中使用?dhtmlxGantt?組件時(shí)遇到的問(wèn)題匯總(推薦)
dhtmlxGantt一個(gè)功能豐富的甘特圖插件,支持任務(wù)編輯,資源分配和多種視圖模式,這篇文章主要介紹了在?Vue?中使用?dhtmlxGantt?組件時(shí)遇到的問(wèn)題匯總,需要的朋友可以參考下2023-03-03對(duì)vue中v-on綁定自定事件的實(shí)例講解
今天小編就為大家分享一篇對(duì)vue中v-on綁定自定事件的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09關(guān)于Vue?ui?的沒(méi)反應(yīng)、報(bào)錯(cuò)問(wèn)題解決總結(jié)
這篇文章主要介紹了關(guān)于Vue?ui?的沒(méi)反應(yīng)、報(bào)錯(cuò)問(wèn)題解決總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09Vue3在Setup中使用axios請(qǐng)求獲取的值方式
這篇文章主要介紹了Vue3在Setup中使用axios請(qǐng)求獲取的值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06vue3?ts編寫(xiě)echart是tooltip無(wú)法展示的解決
這篇文章主要介紹了vue3?ts編寫(xiě)echart是tooltip無(wú)法展示的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10