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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:54:55