Vue 的多个模态组件

新手上路,请多包涵

我在 Vue 中实现动态模态组件时遇到问题。

我用来显示从数据库中获取的一组数据的常用方法是,我通过遍历数据库结果的每一行来转储 HTML 表格元素中的每一行。是这样的: 在此处输入图像描述

正如您在屏幕截图中看到的,每一行都有一个或多个由循环动态生成的按钮。为了将模态组件绑定到每个按钮(比如本场景中的删除按钮),我做了这样的事情。

HTML:

 <div id="app">
    <?php foreach($result as $x): ?>
        <modal v-if="showModal">I am Modal $x</modal>
        <btn @trigger="onShowModal">Button $x</btn>
    <?php endforeach; ?>
</div>

因此,如果我的结果中有三行,上述代码块将采用如下形式:

 <div id="app">
        <modal v-if="showModal">I am Modal 1</modal>
        <btn @trigger="onShowModal">Button 1</btn>

        <modal v-if="showModal">I am Modal 2</modal>
        <btn @trigger="onShowModal">Button 2</btn>

        <modal v-if="showModal">I am Modal 3</modal>
        <btn @trigger="onShowModal">Button 3</btn>
</div>

这是我在 JavaScript 端所做的:

脚本:

     Vue.component('btn',{
      template: `<button @click="$emit('trigger')"><slot></slot></button>`,
    });

    Vue.component('modal',{
      template: `<p><slot></slot></p>`,
    });

    new Vue({
      el: '#app',
      data: {
        showModal: false
      },
      methods: {
        onShowModal(){
          this.showModal = true;
        }
      }
    });

这种方法的问题是,当我单击任何一个“删除”按钮时,我得到的是模态“堆栈”而不是我想查看的模态。那是因为我将 showModal 设置为 true 如果你看到填充的 HTML 块,你会看到每个模态都设置为 v-if="showModal"

单击此处查看演示

随着我开始了解前端-后端关系,我了解到这种模式在应用程序中出现得越来越频繁。我该如何解决这个问题(对 vue 初学者非常友好)?

原文由 Tanmay 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 798
2 个回答

根本问题是您在所有模态组件上引用相同的数据属性 showModal

您可以制作另一个组件来封装按钮和模态组件对。这样,每个 modalbtn 对都有一个单独的 showModal 数据属性:

 Vue.component('btn',{
  template: `<button @click="$emit('trigger')"><slot></slot></button>`,
});

Vue.component('modal',{
  template: `<p><slot></slot></p>`,
});

Vue.component('modal-btn', {
  template: `
    <div>
      <modal v-if="showModal">
        <slot>I am a modal</slot>
      </modal>
      <btn @trigger="showModal = true">Show Modal</btn>
    </div>
  `,
  data() {
    return { showModal: false }
  }
});

new Vue({
  el: '#app',
  data: {
    showModal: false
  },
  methods: {
    onShowModal(){
      this.showModal = true;
    }
  }
});
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<div id="app">
  <modal-btn></modal-btn>
  <modal-btn>I am another modal</modal-btn>
  <modal-btn>I'm a third modal</modal-btn>
</div>

原文由 thanksd 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可能需要一种更加以数据为中心的方法来解决您正在尝试的问题。就像是,

 <!DOCTYPE html>
<html>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
</head>
<body>
  <div id="app">
    <template v-for="item in items">
      <modal v-if="item.show">I am a dummy Modal for {{item.name}}</modal>
      <btn @trigger="item.show = !item.show">Button for {{item.id}}</btn>
    </template>
  </div>

  <script>
    Vue.component('btn',{
      template: `<button @click="$emit('trigger')"><slot></slot></button>`,
    });

    Vue.component('modal',{
      template: `<p><slot></slot></p>`,
    });

    new Vue({
      el: '#app',
      data: {
        items: [
          {id: 1, name: 'item 1', show: false},
          {id: 2, name: 'item 2', show: false},
          {id: 3, name: 'item 3', show: false}
        ],
        showModal: false
      },
      methods: {
        onShowModal(){
          this.showModal = true;
        }
      }
    });
  </script>
</body>
</html>

然后,您还可以使用单个 modal 组件接收它应该通过 prop 显示的适用数据

原文由 Leon Vismer 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题