網(wǎng)站右側(cè) 回到頂部站長工具流量統(tǒng)計
v-model是語法糖,常和ref 配合使用
v-model
?是視圖層的雙向綁定工具,而?ref
?是邏輯層的響應(yīng)式數(shù)據(jù)載體或?qū)嵗霉ぞ?/strong>。兩者在表單場景中通過 “v-model
?綁定?ref
?數(shù)據(jù)” 產(chǎn)生關(guān)聯(lián),但本質(zhì)上解決的是不同層面的問題。ref在更底層。
為啥需要ref呢 vue畢竟是js為基,js 給基本變量賦值 ,是復(fù)制方式 不是引用啊,所以要用ref包裝進行處理。
v-model
:雙向綁定指令
本質(zhì)是語法糖,用于表單元素(如 input、select 等)實現(xiàn)數(shù)據(jù)與視圖的雙向同步,內(nèi)部會自動處理?input
?事件和值綁定(value
?或?modelValue
)。
v-text與v-model
?:
簡單來說:v-text
?是 “看數(shù)據(jù)”,v-model
?是 “改數(shù)據(jù)”,前者用于展示,后者用于交互。
在 Vue3 中,reactive()
?和?toRef()
?雖然都與響應(yīng)式數(shù)據(jù)相關(guān),但它們的核心用途和實現(xiàn)機制不同。理解它們的差異需要從?響應(yīng)式原理?和?引用關(guān)系?兩個角度分析。
1. 核心差異:引用 vs. 代理
-
reactive()
:創(chuàng)建深層響應(yīng)式代理- 將對象轉(zhuǎn)換為響應(yīng)式代理(Proxy),所有嵌套屬性都會被遞歸轉(zhuǎn)為響應(yīng)式。
- 切斷了原始對象與代理的直接引用關(guān)系(原始對象修改不會影響代理)。
- 示例:
import { reactive } from 'vue';const original = { name: '張三' }; const state = reactive(original);// 修改原始對象不會影響響應(yīng)式代理 original.name = '李四'; console.log(state.name); // 仍為 '張三'
-
toRef()
:創(chuàng)建單個屬性的響應(yīng)式引用- 保持對原始對象屬性的?只讀引用,不創(chuàng)建新的響應(yīng)式對象。
- 雙向同步原始對象與引用(原始對象修改會影響引用,反之亦然)。
- 示例:
import { toRef } from 'vue';const original = { name: '張三' }; const nameRef = toRef(original, 'name');// 修改原始對象會影響引用 original.name = '李四'; console.log(nameRef.value); // 變?yōu)?'李四'
2. 為什么?需要?toRef()
(1)在解構(gòu)響應(yīng)式對象時保持響應(yīng)性
當(dāng)使用?reactive()
?創(chuàng)建的對象被解構(gòu)后,解構(gòu)出的屬性會失去響應(yīng)性,而?toRef()
?可以保持響應(yīng)性。
-
示例:解構(gòu)導(dǎo)致響應(yīng)性丟失
import { reactive } from 'vue';const state = reactive({ name: '張三', age: 20 }); const { name } = state; // 解構(gòu)出的 name 不是響應(yīng)式的// 修改 state.name 不會影響 name 變量 state.name = '李四'; console.log(name); // 仍為 '張三'
-
解決方案:使用?
toRef()
?保持響應(yīng)性import { reactive, toRef } from 'vue';const state = reactive({ name: '張三', age: 20 }); const nameRef = toRef(state, 'name'); // 創(chuàng)建響應(yīng)式引用// 修改 state.name 會影響 nameRef.value state.name = '李四'; console.log(nameRef.value); // 變?yōu)?'李四'
(2)在組合式 API 中安全傳遞響應(yīng)式屬性
當(dāng)需要將響應(yīng)式對象的某個屬性傳遞給其他函數(shù)或組件時,使用?toRef()
?可以避免響應(yīng)性丟失。
- 示例:傳遞響應(yīng)式屬性
import { reactive, toRef } from 'vue';const state = reactive({ name: '張三' });// 傳遞 name 屬性的引用 const nameRef = toRef(state, 'name');// 在其他地方使用 nameRef,保持響應(yīng)性 function updateName() {nameRef.value = '李四'; // 修改會同步到 state.name }
(3)與第三方庫集成時保持響應(yīng)性
當(dāng)需要將響應(yīng)式數(shù)據(jù)傳遞給不支持 Vue 響應(yīng)式的第三方庫時,toRef()
?可以作為中間層保持響應(yīng)性。
- 示例:與非響應(yīng)式 API 集成
import { reactive, toRef } from 'vue';const state = reactive({ loading: false });// 將 loading 轉(zhuǎn)換為 ref 形式傳遞給第三方庫 const loadingRef = toRef(state, 'loading');// 第三方庫修改 loadingRef,會同步到 state.loading thirdPartyAPI(loadingRef);
reactive()
:創(chuàng)建一個全新的響應(yīng)式代理對象,切斷與原始對象的直接引用。toRef()
:創(chuàng)建一個指向原始對象屬性的響應(yīng)式引用,保持雙向同步。
使用場景:當(dāng)你需要在不創(chuàng)建新對象的情況下保持某個屬性的響應(yīng)性,或需要解構(gòu)響應(yīng)式對象但不丟失響應(yīng)性時,toRef()
?是最佳選擇。
另外, 什么是解構(gòu)呢,它本質(zhì)上就是語法糖喲,
解構(gòu)的本質(zhì)是:創(chuàng)建獨立變量
解構(gòu)是 JavaScript 的語法糖,用于簡化對象或數(shù)組的屬性提取。它會創(chuàng)建?原始值的副本,而非引用。