多模态弹出窗口 vue.js

3
我目前在工作的研究项目中使用Vue.JS技术。目前,我主要在前端方面工作。我有一张带有几个条目的表格,当单击行时,我想要弹出一个模态窗口,显示该行的更多详细信息。我正在尝试让多个弹出窗口正常工作,并在此正确工作后处理每个弹出窗口中的动态内容。目前,顶部行如下所示已经可以使用:
<tr class="activate-popupmodal-tr" @click="showmodal = true">
                      <td>01/01/2016

                        <modal :show.sync="showmodal">

                          <h3 slot="header">
                            Bug #1 - <span> 04/07/2016 </span>

                            <img src="files/cross.jpg" @click="showmodal = false" />
                          </h3>


                          <div slot="body">
                          </div>

                          <div slot="footer">
                         </div>

                        </modal>
</tr>

使用app.js如下:

Vue.component('modal', {
  template: '#dashboard-popup-template',
  props: {
    show: {
      type: Boolean,
      required: true,
      twoWay: true
    }
  }
})

new Vue({
  el: '.activate-popupmodal-tr',
  data: {
    showmodal: false
  }
})

这个方法可行,但只适用于一行。

有什么办法可以让它适用于所有行吗?

表格:https://jsfiddle.net/a6n04o3t/

1个回答

6

Vue非常灵活,因此您可以以多种不同的方式显示模态框。这是我经常使用的其中一种方式。

您可以在这里的webpackbin中找到一个包含一些丑陋样式的演示。

首先,我从一个父级Vue实例开始,该实例将容纳我的列表组件、模态框组件和我的项目列表(实际上,在这种情况下,项目列表可以存储在父级或列表组件中,但可能希望将其存储在父级中):

// in main.js

new Vue({
  el: 'body',
  components:{
    list: List,
    modal: Modal
  },
  data:{
    items:[
      {name: 'foo'},
      {name: 'bar'},
      {name: 'baz'}
    ]
  },
  events:{
    showModal: function(item){
      this.$broadcast('showModal', item)
    }
  }
})

此外,它还拥有一个桥接事件,即用于监听来自子组件的$dispatch事件,并立即向不同的子组件广播相应的事件,如果需要则传递数据。稍后我们将更详细地讨论这一点。

我的索引文件将包含listmodal组件的占位符,它们将被各自对应的组件模板替换:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <style>
        ...
    </style>
  </head>
  <body>
    <div class="list-container">
      <list :items="items"></list>
    </div>

    <modal></modal>

    <script src="main.js"></script>
  </body>
</html>

请注意代码行<list :items="items"></list>。这里我们将从父组件传入的items传递给list子组件。
然后我创建了一个列表组件来显示我的列表:
// also in main.js

var List = Vue.component('list',{
  props:['items'],
  template: `
<div class="list-row" v-for="item in items" @click="showModal(item)">
  <span>{{ item.name }}</span>
</div>
`,
  methods:{
    showModal: function(item){
      this.$dispatch('showModal', item)
    }
  }
})

列表组件接受items作为属性,以便它可以通过在列表组件的模板中使用v-for="item in items"来显示每个项目。
对于列表中呈现的每一行,我都会附加一个点击事件,调用方法showModal并将当前item传递给它。该方法然后向父级分发showModal事件。
这就是父元素中桥接事件的作用。父元素的showModal事件监听来自列表的分发,并立即向所有子代广播showModal事件,并传递当前项目。
唯一具有showModal事件监听器的子代是modal组件:
// also in main.js 

var Modal = Vue.component('modal',{
  template:`
<div class="modal-container" v-show="visible">
  <div class="modal-body">
    <div clas="modal-content">
      {{ item | json }}  
    </div>
    <button @click="closeModal">Close</button>
  </div>
</div>
`,
  data: function(){
    return {
      item: null,
      visible: false
    }
  },
  events:{
    showModal: function(item){
      this.item = item
      this.visible = true
    }
  },
  methods:{
    closeModal: function(){
      this.visible = false
      this.item = null
    }
  }
})

当模态组件检测到从父组件广播了showModal时,它会触发showModal事件逻辑,将传入的项设置为本地属性(这使得模态框的模板可以访问它),并将可见性设置为true。
我使用这种模式来显示模态框、加载遮罩、通知等等。
如果您对这种方法有任何疑问,请告诉我。

2
这正是我正在寻找的!感谢您抽出时间回答我的问题。 - Provoke
没问题。我很高兴能帮到你 :) - Chris Schmitz
1
这种设计模式一次只能显示一个模态框,对吧?如果要同时允许多个模态框,则应该将与行数相同的<modal></modal>组件放入模板中(并稍微更改事件分派),对吧?但是我们可以重用一个模态框组件,每次只需克隆它或进行其他操作即可吗? - Ruslan Stelmachenko
1
无法在Vue.js 2中使用,因为事件只能从子组件传递到父组件。相反,您需要一个“事件总线”。 - northernman
继@djxak之后,是否可以堆叠多个模态框而不是同一个改变状态?我正在尝试在vue2中实现以下内容:模态框打开以编辑帐户详细信息,发生某些事情并且您的会话过期,认证模态框出现在顶部,您进行身份验证并继续编辑帐户详细信息,就像您离开时一样。 - PanPipes
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接