You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:55:02