Vue自定义Bootstrap模态框复用异常:编辑组件渲染创建表单内容
问题:点击Edit按钮触发模态框时显示CreateData表单内容
问题原因
自定义模态框组件中硬编码了固定ID staticBackdrop,当CreateData和EditData组件同时引入该模态框组件后,页面会存在多个相同ID的模态框元素。Bootstrap通过ID匹配触发目标时,只会找到页面中第一个匹配ID的模态框,因此点击Edit按钮会错误打开CreateData对应的模态框。
解决方案
给模态框组件添加动态唯一ID,通过props传入,确保每个模态框实例的ID不重复,同时让触发按钮与对应模态框的ID绑定。
1. 修改模态框组件(BackdropDialogCloseSuccess.vue)
<template> <button type="button" :class="btnClass" :data-bs-toggle="modalId ? 'modal' : ''" :data-bs-target="modalId ? `#${modalId}` : ''" > <slot name="btn-title"></slot> </button> <div class="modal fade" :id="modalId" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" :aria-labelledby="`${modalId}Label`" aria-hidden="true" ref="theModal" > <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" :id="`${modalId}Label`"> <slot name="dialog-header"></slot> </h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" ></button> </div> <div class="modal-body"> <slot></slot> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" > Close </button> <button type="button" class="btn btn-primary" @click="success()"> Ok </button> </div> </div> </div> </div> </template> <script> import { Modal } from "bootstrap"; export default { props: { btnClass: String, modalId: { type: String, default: "staticBackdrop" // 默认值兼容原有使用场景 } }, emits: ["on-success"], data() { return { theModal: null, }; }, methods: { success() { this.$emit("on-success", this.theModal); }, }, mounted() { this.theModal = new Modal(this.$refs.theModal); }, }; </script>
2. 修改CreateData组件(AddNewCompany.vue)
传入唯一的modalId:
<template> <backdrop-dialog-close-success btnClass="btn btn-success" modalId="createCompanyModal" @onSuccess="onSuccess" > <!-- 原有插槽内容保持不变 --> </backdrop-dialog-close-success> </template>
3. 修改EditData组件(EditCompany.vue)
传入另一个唯一的modalId:
<template> <BackdropDialogCloseSuccess btnClass="btn btn-outline-warning" modalId="editCompanyModal" > <!-- 原有插槽内容保持不变 --> </BackdropDialogCloseSuccess> </template>
额外优化建议
如果希望更贴合Vue的响应式开发模式,可以去掉data-bs-toggle和data-bs-target的DOM绑定方式,改为通过组件方法手动控制模态框显示:
- 在模态框组件中添加
show()方法,内部调用this.theModal.show() - 父组件通过ref调用该方法触发模态框,彻底避免ID冲突问题
内容的提问来源于stack exchange,提问作者Piyush
相关产品推荐
相关产品推荐

