Bootstrap-Vue 模态:如何在 V-For 渲染列表中打开不同的模态?

Posted

技术标签:

【中文标题】Bootstrap-Vue 模态:如何在 V-For 渲染列表中打开不同的模态?【英文标题】:Bootstrap-Vue Modal: How to open different modals in an V-For rendered list? 【发布时间】:2021-10-19 05:22:13 【问题描述】:

我正在使用 Bootstrap-Vue 模式打开一个“编辑”模式,当单击附加到我在 v-for 渲染列表中渲染的每个项目的“编辑”按钮时。

然而,每次当我点击编辑按钮时,它都会打开所有的模态,堆叠在一起,列表中的最后一个元素是顶部的模态。

如何指定它只打开被点击编辑的项目的模态/信息?

//Parent Component

<div class="dataList">
 <div v-bind:key="item.id" v-for="item in this.$store.getters.data">
    <Child v-bind:item="item"></Child>
 </div>
</div>



//Child Component
<div>
      this.item.name
      this.item.details
      this.item.completedBy
      this.item.status
      <button v-b-modal.modal-1>Edit</button>
      <button v-on:click="deleteItem">Delete</button>

      <div>
        <b-modal id="modal-1" title="BootstrapVue">
          <form @submit="editItem">
              <input v-model="name">
              <input v-model="details">
              <input v-model="completedBy">
              <select v-model="status">
                  <option>Fail</option>
                  <option>Warn</option>
                  <option>Pass</option>
              </select><br>
              <input type="submit" value="Submit" @click="$bvModal.hide('modal-1')">
          </form>
        </b-modal>
      </div>
  </div>


现在每个模态都显示正确的信息(如正确的名称、详细信息、状态等),但我只需要特定的模态。

我想它与“vb-modal.modal-1”有关,但我不确定如何动态设置每个模态的 id...有没有办法轻松地将每个模态 id 设置为匹配 item.id?

这里是 Bootstrap-Vue 模态的文档,但我没有找到我需要的。

【问题讨论】:

旁注,您不需要(也不应该)在模板中使用this.。它可能会导致渲染问题。 【参考方案1】:

我建议将&lt;b-modal&gt; 移出您的v-for。 这样你就只有一个了。

然后您改为将要编辑的用户/项目设置为变量,并在您的模式中利用它来显示所选用户的数据。

示例

new Vue(
  el: "#app",
  data() 
    return 
      selectedUser: null,
      items: [
          name: "Name 1",
          status: "Fail",
          details: "Details 1"
        ,
        
          name: "Name 2",
          status: "Warn",
          details: "Details 2"
        
      ]
    
  ,
  methods: 
    editUser(user) 
      this.selectedUser = user;
      this.$bvModal.show("edit-modal");
    
  
)
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap@4.5.3/dist/css/bootstrap.min.css" />
<link href="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.css" rel="stylesheet" />

<script src="//unpkg.com/vue@2.6.12/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.min.js"></script>


<div id="app" class="p-4">
  <div v-for="item in items" class="mt-3">
    item.name item.details item.status

    <b-btn variant="primary" @click="editUser(item)">Edit</b-btn>
    <b-btn variant="danger">Delete</b-btn>
  </div>
  <b-modal id="edit-modal" title="Edit User">
    <form v-if="selectedUser">
      <input v-model="selectedUser.name">
      <input v-model="selectedUser.details">
      <input v-model="selectedUser.completedBy">
      <select v-model="selectedUser.status">
        <option>Fail</option>
        <option>Warn</option>
        <option>Pass</option>
      </select><br>
      <input type="submit" value="Submit">
    </form>
  </b-modal>
</div>

如果您想将模态框保留在您的v-for 中,您必须给它一个唯一的id。如果您的商品有一个,我建议您使用它,否则您可以使用 v-for 中的 index

简化示例

<div v-for="item in items">
  <button v-b-modal:[`edit-modal-$item.id`]>Edit Item</button>
 
  <b-modal :id="`edit-modal-$item.id`">
    <!-- Modal Content-->
  </b-modal>
</div>

【讨论】:

刚刚注意到您在子组件中有模式。这意味着如果您想使用第一个示例,则必须将模态移出组件并在单击编辑按钮时执行$emit 以让父级知道显示模态。所以第二个例子对你来说可能更容易实现。 这个简化的例子成功了。我只是使用 v-for 索引并将其传递给 b-modal 的 id 和按钮 v-b-modal 以正确 id 并打开正确的模态。谢谢!【参考方案2】:

一种最快速但可能不是最好的方法是条件渲染模态框。

您可以在单击编辑时通过将 prop/data/var 设置为 activeModal: 1 或 n 来切换活动模式编号/索引。

然后在您迭代模态的部分,您可以对模态使用 v-if 指令,例如:&lt;v-modal v-if="activeModal"&gt; 这将是一种忽略/不呈现其他模态的方法,但每次“编辑”点击都会重新呈现。

最佳/最终解决方案是将 vue-portal 内容传送到单个通用模式。

【讨论】:

以上是关于Bootstrap-Vue 模态:如何在 V-For 渲染列表中打开不同的模态?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 vue-test-utils 打开 bootstrap-vue 模态?

如何从 vuex 操作中调用 bootstrap-vue 模态和 toast?

在 bootstrap-vue 模态(b-modal)int 测试中找不到按钮

如何在 bootstrap-vue modal[b-modal] 上创建过渡/动画

在模态自动对焦上引导 vue 输入

需要增加 b 模态宽度。 Vue JS.Bootstrap