VueJs:如何重用 bootstrap 模态对话框

VueJs: How to reuse bootstrap modal dialog

我创建了三个简单的按钮,它们将触发三个不同的 bootstrap 模式对话框。模式对话框是 "Add Product""Edit Product""Delete Product". AddEdit 模态对话框都包含一个带有两个输入元素的表单,而 Delete 模态对话框包含一个简单的文本。我意识到我的代码变得非常混乱并且难以维护。因此,我有以下问题:

1) 如何重用模态对话框,而不是创建 3 个单独的对话框?

2) 我如何知道触发了哪个模态对话框?

更新:我开发了一个灵魂,我将在其中包含条件语句,例如 v-if、v-else-if 和 v-else 来跟踪用户点击了哪个按钮。但是,我仍然觉得有更好的解决方案。任何人都可以 help/advice 我吗?

下面是我当前的代码:

       <template>
  <div>
    <b-button v-b-modal.product class="px-4" variant="primary" @click="addCalled()">Add</b-button>
    <b-button v-b-modal.product class="px-4" variant="primary" @click="editCalled()">Edit</b-button>
    <b-button v-b-modal.product class="px-4" variant="primary" @click="deleteCalled()">Delete</b-button>

    <!-- Modal Dialog for Add Product -->
    <b-modal id="product" title="Add Product">
      <div v-if="addDialog">
        <form @submit.stop.prevent="submitAdd">
          <b-form-group id="nameValue" label-cols-sm="3" label="Name" label-for="input-horizontal">
            <b-form-input id="nameValue"></b-form-input>
          </b-form-group>
        </form>

        <b-form-group id="quantity" label-cols-sm="3" label="Quantity" label-for="input-horizontal">
          <b-form-input id="quantity"></b-form-input>
        </b-form-group>
      </div>

      <div v-else-if="editDialog">
        <form @submit.stop.prevent="submitEdit">
          <b-form-group id="nameValue" label-cols-sm="3" label="Name" label-for="input-horizontal">
            <b-form-input id="nameValue" :value="productName"></b-form-input>
          </b-form-group>
        </form>

        <b-form-group id="quantity" label-cols-sm="3" label="Quantity" label-for="input-horizontal">
          <b-form-input id="quantity" :value="productQuantity">5</b-form-input>
        </b-form-group>
      </div>

      <div v-else>
        <p class="my-4">Are You Sure you want to delete product?</p>
      </div>
    </b-modal>
  </div>
</template>

<script>
export default {
  data() {
    return {
      productName: "T-Shirt",
      productQuantity: 10,
      addDialog: false,
      editDialog: false,
      deleteDialog: false
    };
  },
  methods: {
    addCalled() {
      this.addDialog = true;
    },
    editCalled() {
      this.editDialog = true;
      this.addDialog = false;
      this.deleteDialog = false;
    },
    deleteCalled() {
      this.deleteDialog = true;
      this.addDialog = false;
      this.editDialog = false;
    }
  }
};
</script>

<style>
</style>

更新

现在,您可能会想如何关闭您的模式并让父组件知道它。 单击按钮触发 closeModal

创建一个方法 - closeModal 并在 commonModal 组件内部和 emit 一个事件。

closeModal() { 
  this.$emit('close-modal')
}

现在这将发出一个可以被消费组件侦听的自定义事件。

因此在您的父组件中只需使用此自定义事件,例如关注并关闭您的模态

<main class="foo">
  <commonModal v-show="isVisible" :data="data" @close- modal="isVisible = false"/>
  <!-- Your further code -->
</main>

所以根据你的问题

A - 如何重用模式对话框,而不是创建 3 个单独的对话框

创建一个单独的 modal 组件,比如说 - commonModal.vue.

现在在你的 commonModal.vue 中,接受单曲 prop,比如说 data: {}

现在在 commonModalhtml 部分

<div class="modal">
  <!-- Use your received data here which get received from parent -->
  <your modal code />
</div>

现在将 commonModal 导入 consuming/parent 组件。在父组件中创建数据 属性,比方说 - isVisible: false,并为要在 modal 中显示的 data 计算 属性 比方说 modalContent.

现在这样使用

<main class="foo">
   <commonModal v-show="isVisible" :data="data" />
   <!-- Your further code -->
</main>

以上将帮助你 re-use 模态,你只需要从父组件发送 data

现在第二个问题也会在这里得到解决我怎么知道触发了哪个模态对话框?

只需验证 isVisible 属性 即可检查 modal 是否打开。如果 isVisible = false 那么你的模式不可见并且 vice-versa

如前所述,我会使用插槽和动态组件呈现来以更简洁的方式完成您想要做的事情。

请参阅下面的代码片段(我没有将它们设为模态,但想法是一样的)。

这样,您就可以拥有一个处理共享逻辑或样式的通用 modal 组件,以及根据需要通过专用插槽注入的 modalContentsub-components 组件。

Vue.component('modal', {
  template: `
    <div>
      <h1>Shared elements between modals go here</h1>
      <slot name="content"/>
    </div>
  `
});


Vue.component('modalA', {
  template: `
    <div>
      <h1>I am modal A</h1>    
    </div>
  `
});

Vue.component('modalB', {
  template: `
    <div>
      <h1>I am modal B</h1>    
    </div>
  `
});

Vue.component('modalC', {
  template: `
    <div>
      <h1>I am modal C</h1>    
    </div>
  `
});


new Vue({
  el: "#app",
  data: {
    modals: ['modalA', 'modalB', 'modalC'],
    activeModal: null,
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <button v-for="modal in modals" @click="activeModal = modal"> Open {{ modal }} </button>
  <modal>
    <template slot="content">
      <component :is="activeModal"></component>
    </template>
  </modal>
</div>