【vue3】watch、watchEffect、watchPostEffect和watchSyncEffect的区别详解
watch
监听属性变化
<template><button @click="handleClick">add</button>
</template><script lang="ts" setup>
const number = ref(1);
const handleClick = () => {number.value++;
};watch(() => number.value,(newVal, oldValue) => {console.log(newVal, "数据变化了");},
);
</script>
watchEffect
自动追踪依赖的副作用
与wacth区别相当于加{immediate: true}
<template><button @click="handleClick">add</button>
</template><script lang="ts" setup>
const number = ref(1);
const handleClick = () => {number.value++;
};watch(() => number.value,(newVal, oldValue) => {console.log(newVal, "数据变化了");},{ immediate: true }
);
watchEffect(()=>{consloe.log(number.value,"数据变化了")
})
</script>
watchPostEffect
dom更新完执行
相当于watch加{ immediate: true , flush: 'post'}
<template><button @click="handleClick">add</button>
</template><script lang="ts" setup>
const number = ref(1);
const handleClick = () => {number.value++;
};watch(() => number.value,(newVal, oldValue) => {console.log(newVal, "数据变化了");},{ immediate: true, flush: "post" }
);
// 等同于
watchEffect(() => {console.log(number.value, "数据变化了");// 清理函数示例(组件卸载或依赖变化前执行)return () => {console.log("清理副作用");};},{ flush: "post" }
);
</script>
watchSyncEffect
数据变化立马执行
相当于watch加{ immediate: true, flush: "sync" }
<template><button @click="handleClick">add</button>
</template><script lang="ts" setup>
const number = ref(1);
const handleClick = () => {number.value++;
};watch(() => number.value,(newVal, oldValue) => {console.log(newVal, "数据变化了");},{ immediate: true, flush: "sync" }
);
// 等同于
watchEffect(()=>{console.log(number.value, "数据变化了");
}, {flush: 'sync'
})
</script>
区别
特性 | watch | watchEffect | watchPostEffect | watchSyncEffect |
---|---|---|---|---|
监听源 | 需手动指定 | 自动追踪依赖 | 自动追踪依赖 | 自动追踪依赖 |
初始化执行 | 默认不执行(可配置) | 立即执行 | 立即执行 | 立即执行 |
新旧值获取 | 可以 | 不可以 | 不可以 | 不可以 |
执行时机 | DOM 更新前 | DOM 更新前 | DOM 更新后 | 同步执行(阻塞 DOM) |
适用场景 | 需精确控制监听源和值对比 | 多依赖副作用,无需值对比 | 依赖 DOM 更新的副作用 | 需同步执行的特殊场景 |
建议
- 需明确监听源、需要新旧值对比 → 使用
watch
- 多依赖自动追踪、无需值对比 → 使用
watchEffect
- 依赖 DOM 更新后的状态 → 使用
watchPostEffect
- 必须同步执行副作用 → 使用
watchSyncEffect
(谨慎使用)