WatchEffect 在观察反应对象时被触发两次
WatchEffect is triggered twice when watching a reactive object
如果我运行这个代码:
const state = reactive({
title: '',
})
watchEffect(() => {
console.log(state.title)
})
watchEffect
被触发,控制台输出一个空 string
:
""
如果我想给state.title
赋一个新值,watchEffect
会被触发两次。这种行为是预期的还是我做错了什么?
根据the documentation,watchEffect
Runs a function immediately [emphasis added] while reactively tracking its dependencies
and re-runs it whenever the dependencies are changed.
所以预计在这种情况下它应该运行两次:第一次定义时,然后值更改时再次
正如@MykWillis 指出并在文档中明确指出的那样,watchEffect
运行 立即和后续更改,与 watch
和 { immediate: true }
完全一样。
如果您最初不希望效果为 运行,请不要使用 watchEffect
,而是使用 watch
:
const { createApp, watchEffect, reactive, toRefs, watch } = Vue;
createApp({
setup() {
const state = reactive({
title: 'test',
});
watchEffect(() => {
console.log('watchEffect', state.title)
});
watch(() => state.title, () => {
console.log('watch', state.title)
});
watch(() => state.title, () => {
console.log('watch.immediate', state.title)
}, { immediate: true })
return { ...toRefs(state) }
}
}).mount('#app')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="app">
<input v-model="title">
</div>
如果我运行这个代码:
const state = reactive({
title: '',
})
watchEffect(() => {
console.log(state.title)
})
watchEffect
被触发,控制台输出一个空 string
:
""
如果我想给state.title
赋一个新值,watchEffect
会被触发两次。这种行为是预期的还是我做错了什么?
根据the documentation,watchEffect
Runs a function immediately [emphasis added] while reactively tracking its dependencies and re-runs it whenever the dependencies are changed.
所以预计在这种情况下它应该运行两次:第一次定义时,然后值更改时再次
正如@MykWillis 指出并在文档中明确指出的那样,watchEffect
运行 立即和后续更改,与 watch
和 { immediate: true }
完全一样。
如果您最初不希望效果为 运行,请不要使用 watchEffect
,而是使用 watch
:
const { createApp, watchEffect, reactive, toRefs, watch } = Vue;
createApp({
setup() {
const state = reactive({
title: 'test',
});
watchEffect(() => {
console.log('watchEffect', state.title)
});
watch(() => state.title, () => {
console.log('watch', state.title)
});
watch(() => state.title, () => {
console.log('watch.immediate', state.title)
}, { immediate: true })
return { ...toRefs(state) }
}
}).mount('#app')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="app">
<input v-model="title">
</div>