Vue3中watch/onUpdated触发异常:重复赋值无法唤起Modal
解决方案:Vue3中重复设置相同值时触发watch/弹窗显示
问题根源
你遇到的问题是Vue的响应式批量更新机制导致的:在同一个同步代码块里连续修改targetId的两次赋值会被Vue合并,子组件只会接收到最终的id值,中间的0不会触发watch回调,所以弹窗仍无法显示。
可行方案
方案1:用nextTick拆分两次赋值
把第二次赋值放到nextTick中,让Vue分两次处理响应式更新,子组件的watch就能捕获到两次变化:
<!-- 父组件 --> <template> <button @click="showDeleteModal(someId)">Delete</button> <Modal :id="targetId"/> </template> <script setup> import { ref, nextTick } from 'vue' const targetId = ref(0) const showDeleteModal = async (id)=>{ targetId.value = 0 await nextTick() // 等待响应式更新完成 targetId.value = id } </script>
方案2:直接调用子组件的显示方法(更直接)
不需要依赖props变化触发watch,通过ref获取子组件实例,直接调用弹窗显示方法,彻底绕开值相同的问题:
<!-- 父组件 --> <template> <button @click="showDeleteModal(someId)">Delete</button> <Modal ref="modalRef"/> </template> <script setup> import { ref } from 'vue' const modalRef = ref(null) const showDeleteModal = (id)=>{ // 直接调用子组件方法并传递id modalRef.value.showModal(id) } </script> <!-- 子组件(Modal) --> <template> <div class="modal" ref="modalElement"> <!-- 弹窗内容 --> </div> </template> <script setup> import { ref, defineExpose } from 'vue' const modalElement = ref(null) const showModal = (id)=>{ // 执行Bootstrap弹窗显示逻辑 const modal = new bootstrap.Modal(modalElement.value) modal.show() // 可在此保存id用于后续删除操作 } // 暴露方法给父组件调用 defineExpose({ showModal }) </script>
方案3:给watch配置同步刷新(仅作参考)
给子组件的watch添加flush: 'sync'配置,让watch同步触发,但仍需拆分赋值:
<!-- 子组件(Modal) --> <script setup> const props = defineProps({id: Number}) watch(()=>props.id, ()=>{ // 显示弹窗 }, { flush: 'sync' }) </script> <!-- 父组件需搭配nextTick使用 --> <script setup> const showDeleteModal = async (id)=>{ targetId.value = 0 await nextTick() targetId.value = id } </script>
最佳实践推荐
优先选择方案2,它逻辑更直接,无需依赖响应式更新的间接触发,代码可读性和维护性更高,也避免了响应式机制带来的潜在问题。
内容的提问来源于stack exchange,提问作者Jobber T
相关产品推荐
相关产品推荐

