vue3中watch監(jiān)聽(tīng)不同數(shù)據(jù)源的方法總結(jié)
在 Vue 3 中,watch 監(jiān)聽(tīng)不同數(shù)據(jù)源的方式有所不同
1. 監(jiān)聽(tīng)單個(gè) ref
import { ref, watch } from 'vue'
const count = ref(0)
// 直接傳入 ref
watch(count, (newVal, oldVal) => {
console.log('count 變化:', newVal, oldVal)
})
// 或者使用 getter 函數(shù)
watch(() => count.value, (newVal, oldVal) => {
console.log('count 變化:', newVal, oldVal)
})
2. 監(jiān)聽(tīng)多個(gè) ref
import { ref, watch } from 'vue'
const count = ref(0)
const name = ref('John')
// 方式1:使用數(shù)組
watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
console.log('count 變化:', newCount, oldCount)
console.log('name 變化:', newName, oldName)
})
// 方式2:使用 getter 數(shù)組
watch(
[() => count.value, () => name.value],
([newCount, newName], [oldCount, oldName]) => {
console.log('多個(gè)數(shù)據(jù)變化')
}
)
3. 監(jiān)聽(tīng)單個(gè) reactive
import { reactive, watch } from 'vue'
const state = reactive({
count: 0,
name: 'John'
})
// ? 錯(cuò)誤:直接傳入 reactive 對(duì)象無(wú)法監(jiān)聽(tīng)到內(nèi)部屬性的變化
watch(state, (newVal, oldVal) => {
console.log('不會(huì)觸發(fā)') // 深度監(jiān)聽(tīng)時(shí)才會(huì)觸發(fā)
})
// ? 正確:使用 getter 函數(shù)監(jiān)聽(tīng)特定屬性
watch(
() => state.count,
(newVal, oldVal) => {
console.log('count 變化:', newVal, oldVal)
}
)
// ? 深度監(jiān)聽(tīng)整個(gè) reactive 對(duì)象
watch(
() => state,
(newVal, oldVal) => {
console.log('state 任何屬性變化都會(huì)觸發(fā)')
},
{ deep: true }
)
4. 監(jiān)聽(tīng)多個(gè) reactive 數(shù)據(jù)
import { reactive, watch } from 'vue'
const state1 = reactive({ count: 0 })
const state2 = reactive({ name: 'John' })
// 方式1:使用 getter 數(shù)組
watch(
[() => state1.count, () => state2.name],
([newCount, newName], [oldCount, oldName]) => {
console.log('數(shù)據(jù)變化')
}
)
// 方式2:深度監(jiān)聽(tīng)整個(gè) reactive 對(duì)象(不推薦)
watch(
[() => state1, () => state2],
([newState1, newState2], [oldState1, oldState2]) => {
// 注意:oldState1 和 newState1 指向同一個(gè)對(duì)象
console.log('狀態(tài)變化')
},
{ deep: true }
)
5. 混合監(jiān)聽(tīng) ref 和 reactive
import { ref, reactive, watch } from 'vue'
const count = ref(0)
const state = reactive({ name: 'John', age: 18 })
watch(
[count, () => state.name, () => state.age],
([newCount, newName, newAge], [oldCount, oldName, oldAge]) => {
console.log('混合數(shù)據(jù)變化')
}
)
6. 監(jiān)聽(tīng)響應(yīng)式對(duì)象的屬性
import { reactive, watch } from 'vue'
const user = reactive({
info: {
name: 'John',
address: {
city: 'Beijing'
}
}
})
// 監(jiān)聽(tīng)嵌套屬性
watch(
() => user.info.address.city,
(newVal, oldVal) => {
console.log('城市變化:', newVal, oldVal)
}
)
// 深度監(jiān)聽(tīng)整個(gè)對(duì)象
watch(
() => user,
(newVal, oldVal) => {
console.log('user 任何變化')
},
{ deep: true }
)
總結(jié)對(duì)比
| 數(shù)據(jù)源 | 監(jiān)聽(tīng)方式 | 注意事項(xiàng) |
|---|---|---|
| 單個(gè) ref | watch(count, callback) | 直接傳入即可 |
| 多個(gè) ref | watch([ref1, ref2], callback) | 使用數(shù)組形式 |
| 單個(gè) reactive 屬性 | watch(() => state.prop, callback) | 必須使用 getter |
| 多個(gè) reactive 屬性 | watch([() => state.prop1, () => state.prop2], callback) | 使用 getter 數(shù)組 |
| 整個(gè) reactive | watch(() => state, callback, { deep: true }) | 必須深度監(jiān)聽(tīng) |
最佳實(shí)踐建議
- 優(yōu)先使用 getter 函數(shù),特別是監(jiān)聽(tīng) reactive 對(duì)象的屬性
- 避免深度監(jiān)聽(tīng)大型對(duì)象,可能會(huì)影響性能
- 注意舊值的引用問(wèn)題:對(duì)于 reactive 對(duì)象,舊值可能與新值相同(因?yàn)橐梦醋儯?/li>
到此這篇關(guān)于vue3中watch監(jiān)聽(tīng)不同數(shù)據(jù)源的方法總結(jié)的文章就介紹到這了,更多相關(guān)vue3 watch監(jiān)聽(tīng)數(shù)據(jù)源內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue中使用pdf.js實(shí)現(xiàn)PDF文檔展示功能實(shí)例
最近做項(xiàng)目遇到在線預(yù)覽和下載pdf文件,試了多種pdf插件,例如jquery.media.js(ie無(wú)法直接瀏覽),最后選擇了pdf.js插件,這篇文章主要介紹了Vue中使用pdf.js實(shí)現(xiàn)PDF文檔展示功能的相關(guān)資料,需要的朋友可以參考下2025-04-04
vue3+elementUI如何動(dòng)態(tài)修改Loading中提示文字
這篇文章主要介紹了vue3+elementUI如何動(dòng)態(tài)修改Loading中提示文字的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
在Vue中實(shí)現(xiàn)頁(yè)面狀態(tài)保存的各種方法
作為前端開(kāi)發(fā)者,你一定遇到過(guò)這樣的場(chǎng)景:用戶在一個(gè)復(fù)雜的表單頁(yè)面填寫(xiě)了大量信息,不小心刷新了頁(yè)面或點(diǎn)擊了返回按鈕,所有數(shù)據(jù)都消失了!所以今天我們來(lái)深入探討在 Vue 中實(shí)現(xiàn)頁(yè)面狀態(tài)保存的各種方法,需要的朋友可以參考下2026-01-01
vue+element使用動(dòng)態(tài)加載路由方式實(shí)現(xiàn)三級(jí)菜單頁(yè)面顯示的操作
這篇文章主要介紹了vue+element使用動(dòng)態(tài)加載路由方式實(shí)現(xiàn)三級(jí)菜單頁(yè)面顯示的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
一篇文章,教你學(xué)會(huì)Vue CLI 插件開(kāi)發(fā)
這篇文章主要介紹了Vue CLI插件開(kāi)發(fā),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Vue3進(jìn)行樣式Scoped和Global的設(shè)置方法
在 Vue 3 中,組件化開(kāi)發(fā)成為了我們提升前端開(kāi)發(fā)效率的利器,其中,樣式的管理也是一個(gè)至關(guān)重要的部分,在 Vue 中,我們會(huì)經(jīng)常使用兩種樣式作用域:Scoped 樣式和 Global 樣式,本文將通過(guò)示例代碼來(lái)介紹Vue3如何進(jìn)行樣式Scoped和Global的設(shè)置,需要的朋友可以參考下2025-01-01

