Vue 3中给ref变量赋值时watch监听器不生效的原因是什么?
问题原因
<script setup> 中的代码是从上到下同步执行的:
- 你先执行了
num.value = 1的赋值操作,此时watch函数还未执行,监听器根本没有完成注册,自然捕获不到这次变更。 - 放在
setTimeout中能触发的原因是,setTimeout属于宏任务,会等待当前所有同步代码(包括后续watch的注册逻辑)全部执行完成后,才会执行回调内的赋值操作,此时监听器已经注册完成,就可以正常捕获变更。
修复方案
有两种常用的修复方式:
- 方案1:调整代码顺序,把
watch的注册逻辑放到赋值操作之前
<script setup> import { ref, watch } from 'vue' const num = ref(null) // 先注册监听器 watch(num, (newVal, oldVal) => { console.log("Num changed to: ", newVal) }) // 再执行赋值操作 if(true) { num.value = 1 } </script>
- 方案2:给
watch添加immediate: true配置,监听器注册完成后会立即执行一次回调,拿到当前最新值,不需要在意赋值和注册的先后顺序
<script setup> import { ref, watch } from 'vue' const num = ref(null) if(true) { num.value = 1 } // 添加immediate配置 watch(num, (newVal, oldVal) => { console.log("Num changed to: ", newVal) }, { immediate: true }) </script>
内容的提问来源于stack exchange,提问作者Andreas Hunter
相关产品推荐
相关产品推荐

