前言
在Vue3中,引入了Composition API,其中的watchEffect()
函數(shù)是一個(gè)非常強(qiáng)大和靈活的工具,用于處理響應(yīng)式數(shù)據(jù)的變化,使得項(xiàng)目更加彈性和靈活。它與watch
有所不同,本文將介紹watchEffect()
的定義、特點(diǎn)、與watch
的區(qū)別以及使用時(shí)的注意事項(xiàng)。
一、定義
watchEffect()
函數(shù)用于創(chuàng)建一個(gè)自動(dòng)追蹤依賴的響應(yīng)式副作用。它會(huì)在初始化時(shí)會(huì)立即執(zhí)行一次,并自動(dòng)追蹤在回調(diào)函數(shù)中使用的所有響應(yīng)式數(shù)據(jù),在這些數(shù)據(jù)發(fā)生變化時(shí)重新運(yùn)行回調(diào)函數(shù)。
例如,在每當(dāng)?todoId
?的引用發(fā)生變化時(shí)使用偵聽器來加載一個(gè)遠(yuǎn)程資源,如果用watch,是這么寫:
<template>
<div>Test</div>
</template>
<script setup>
import { ref, watch } from 'vue'
const todoId = ref(1)
const data = ref(null)
watch(
todoId,
async () => {
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)
data.value = await response.json()
console.log(data.value)
},
{ immediate: true }
)
</script>
打印:
但是用了watchEffect()
就可以簡化為:
<template>
<div>Test</div>
</template>
<script setup>
import { ref, watchEffect } from 'vue'
const todoId = ref(1)
const data = ref(null)
watchEffect(async () => {
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)
data.value = await response.json()
console.log(data.value)
})
</script>
?打印:
兩者都立即打印了data。但下面的例子中,回調(diào)會(huì)立即執(zhí)行,不需要指定?immediate: true
。在執(zhí)行期間,它會(huì)自動(dòng)追蹤?todoId.value
?作為依賴(和計(jì)算屬性類似)。每當(dāng)?todoId.value
?變化時(shí),回調(diào)會(huì)再次執(zhí)行。有了?watchEffect()
,我們不再需要明確傳遞?todoId
?作為源值。
從這個(gè)角度來看,watchEffect()
的作用類似于Vue2中的computed,
即依賴項(xiàng)發(fā)生變化,自己也跟著改變。但與computed
不同,watchEffect()
沒有返回值,而是直接執(zhí)行回調(diào)函數(shù)。
二、特點(diǎn)
watchEffect()
會(huì)自動(dòng)追蹤其回調(diào)函數(shù)中使用的所有響應(yīng)式數(shù)據(jù),并在這些數(shù)據(jù)發(fā)生變化時(shí)重新運(yùn)行回調(diào)函數(shù)。這使得我們無需手動(dòng)指定要監(jiān)聽的具體屬性,減少了代碼的冗余。
? ? 對于這種只有一個(gè)依賴項(xiàng)的例子來說,
watchEffect()
?的好處相對較小。但是對于有多個(gè)依賴項(xiàng)的偵聽器來說,使用?watchEffect()
?可以消除手動(dòng)維護(hù)依賴列表的負(fù)擔(dān)。? ? 此外,如果你需要偵聽一個(gè)嵌套數(shù)據(jù)結(jié)構(gòu)中的幾個(gè)屬性,
watchEffect()
?可能會(huì)比深度偵聽器更有效,因?yàn)樗鼘⒅桓櫥卣{(diào)中被使用到的屬性,而不是遞歸地跟蹤所有的屬性。?
多個(gè)依賴項(xiàng)例子:
<template>
<div>Test</div>
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({
count: 0,
name: 'John',
age: 25
})
// 使用watchEffect()監(jiān)聽count和name的變化
watchEffect(() => {
console.log('count or name changed:', state.count, state.name)
})
// 模擬count和name變化
setTimeout(() => {
state.count = 1 // 輸出'count or name changed: 1 John'
state.name = 'Alice' // 輸出'count or name changed: 1 Alice'
}, 1000)
</script>
打?。?/p>
深度依賴?yán)樱?/p>
<template>
<div>Test</div>
</template>
<script setup>
import { reactive, watchEffect } from 'vue'
const state = reactive({
person: {
name: 'John',
age: 25
},
todos: [
{ text: 'Task 1', completed: false },
{ text: 'Task 2', completed: true },
{ text: 'Task 3', completed: false }
]
})
// 使用watchEffect()監(jiān)聽person對象中name和age的變化
watchEffect(() => {
console.log('person changed:', state.person.name, state.person.age)
})
// 模擬person中name和age的變化
setTimeout(() => {
state.person.name = 'Alice' // 輸出'person changed: Alice 25'
state.person.age = 30 // 輸出'person changed: Alice 30'
}, 1000)
</script>
打?。?/p>
三、與watch的區(qū)別
1. 監(jiān)聽方式不同:watchEffect()
是自動(dòng)追蹤所有使用的響應(yīng)式數(shù)據(jù),而watch
需要手動(dòng)指定要監(jiān)聽的特定屬性。
2. 監(jiān)聽粒度不同:watchEffect()
監(jiān)聽的是響應(yīng)式數(shù)據(jù)的整個(gè)變化,而watch
可以偵聽指定的屬性或表達(dá)式的變化。
3. 計(jì)算屬性處理方式不同:對于計(jì)算屬性,watchEffect()
會(huì)自動(dòng)依賴于計(jì)算屬性使用到的響應(yīng)式數(shù)據(jù),而watch
需要手動(dòng)指定計(jì)算屬性為監(jiān)聽目標(biāo)。
四、注意事項(xiàng)
1. 避免過度監(jiān)聽:由于watchEffect()
會(huì)追蹤使用到的所有響應(yīng)式數(shù)據(jù),因此要確保在回調(diào)函數(shù)中只使用必要的響應(yīng)式數(shù)據(jù),避免造成不必要的渲染開銷。
2. 異步操作需謹(jǐn)慎處理:由于watchEffect()
會(huì)立即執(zhí)行回調(diào)函數(shù),如果在回調(diào)函數(shù)中進(jìn)行異步操作,需要謹(jǐn)慎處理,以免導(dǎo)致意外行為或副作用。文章來源:http://www.zghlxwxcb.cn/news/detail-593762.html
<script setup>
import { watchEffect } from 'vue'
// 它會(huì)自動(dòng)停止
watchEffect(() => {})
// ...這個(gè)則不會(huì)!
setTimeout(() => {
watchEffect(() => {})
}, 100)
</script>
3. 避免無限循環(huán):當(dāng)在watchEffect()
的回調(diào)中修改響應(yīng)式數(shù)據(jù)時(shí),可能會(huì)導(dǎo)致無限循環(huán)。要避免此問題,可以使用watch()
函數(shù)并設(shè)置immediate: true
選項(xiàng),或者使用ref
來存儲(chǔ)臨時(shí)數(shù)據(jù)。文章來源地址http://www.zghlxwxcb.cn/news/detail-593762.html
到了這里,關(guān)于Vue3的watchEffect的妙用,與watch的區(qū)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!