Vue 的多个模态组件 [英] Multiple modal components with Vue

查看:27
本文介绍了Vue 的多个模态组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我用来显示从数据库中获取的一组数据的一种常用方法是通过迭代数据库结果的每一行来转储 HTML 表元素中的每一行.像这样:

正如您在屏幕截图中看到的,每一行都有一个或多个由循环动态生成的按钮.为了将模态组件绑定到每个按钮(例如本场景中的删除按钮),我执行了以下操作.
HTML:

<?php foreach($result as $x): ?><modal v-if="showModal">我是Modal $x</modal><btn @trigger="onShowModal">按钮 $x</btn><?php endforeach;?>

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

<modal v-if="showModal">我是Modal 1</modal><btn @trigger="onShowModal">按钮 1</btn><modal v-if="showModal">我是Modal 2</modal><btn @trigger="onShowModal">按钮 2</btn><modal v-if="showModal">我是Modal 3</modal><btn @trigger="onShowModal">按钮 3</btn>

这是我在 JavaScript 端所做的:

JavaScript:

 Vue.component('btn',{模板:`<button @click="$emit('trigger')"><slot></slot></button>`,});Vue.component('模态',{模板:`<p><slot></slot></p>`,});新的 Vue({el: '#app',数据: {显示模式:假},方法: {onShowModal(){this.showModal = true;}}});

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

点击此处查看演示

当我开始了解前端-后端关系时,我了解到这种模式在应用程序中出现的频率更高.我该如何解决这个问题(非常适合 vue 初学者)?

解决方案

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

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

Vue.component('btn',{模板:`<button @click="$emit('trigger')"><slot></slot></button>`,});Vue.component('模态',{模板:`<p><slot></slot></p>`,});Vue.component('modal-btn', {模板:`<div><modal v-if="showModal"><slot>我是一个模态</slot></modal><btn @trigger="showModal = true">显示模态</btn>

`,数据() {返回 { showModal: false }}});新的 Vue({el: '#app',数据: {显示模式:假},方法: {onShowModal(){this.showModal = true;}}});

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script><div id="应用程序"><modal-btn></modal-btn><modal-btn>我是另一个模态</modal-btn><modal-btn>我是第三模态</modal-btn>

I am having trouble implementing dynamic modal component in Vue.

A common approach I follow to display a set of data fetched from the db is I dump each of the rows in an HTML table element by iterating over each of the row of the db result. Something like this:

As you can see in the screenshot, each of the rows has one or more buttons which are dynamically generated by the loop. In order to bind a modal component to each of the buttons (say the Remove buttons in this scenario) I do something like this.
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>

So if I have three rows in my result, the aforementioned block of code will take the shape of something like this:

<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>

And here is what I do in the JavaScript end:

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;
        }
      }
    });

The problem with this approach is, when I click any one of the Remove buttons, I get a 'stack' of modals instead of the modal I wanted to view. And that's because I am setting showModal to true and if you see the populated HTML block you will see that each of the modals is set to v-if="showModal".

Click here to see a demo

And as I am beginning to understand frontend-backend relationship, I am learning that this pattern is appearing more frequently in an application. How do I fix this issue (with a very vue-beginner-friendly level)?

解决方案

The root issue is that you are referencing the same data property showModal on all of the modal components.

You could make another component to encapsulate the button and modal component pair. This way there is a separate showModal data property for each modal and btn pair:

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>

这篇关于Vue 的多个模态组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
PHP最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆