带Vue的多个模态组件

问题描述:

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

我遵循显示从数据库获取的一组数据的一种常见方法是通过迭代db结果的每一行来转储HTML表格元素中的每一行。像这样:enter image description here

正如你在截图中看到的,每一行都有一个或多个由循环动态生成的按钮。 为了将一个模式组件绑定到每个按钮(比如这个场景中的Remove按钮),我做了这样的事情。
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中底:

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

Click here to see a demo

正如我开始明白前端,后端的关系,我的学习,这种模式在应用程序中更频繁地出现。我如何解决这个问题(一个非常适合初学者的水平)?

根本问题是,您在所有模态组件上引用相同的数据属性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>

+0

接收应该显示适用的数据在一个'模式,button'成分的情况下,单一modal组件脱身,如果我希望数据属性名称和'@ trigger'中的函数是用户提供的,而不是静态的'showModal'和'onShowModal'道具和函数。我的意思是这样的:' modal-button>'? – Eisenheim

+1

在这种情况下,'modal-btn'组件中的'@ trigger'处理程序应该发出一个事件(比如''emit('show')'),然后父组件应该通过' thanksd

+0

谢谢,这会照顾事件的发射。但是如何在''中的'v-if'指令?我如何将v-value的值绑定到用户选择的数据属性说'showConfirmModal'?我坚持使用'' – Eisenheim

您遇到的问题是,所有的情态动词绑定到一个数据属性(showModal),这样所有的情态动词将此设置为true时显示。解决的办法是找出是哪个有它自己的showModal属性,而不是它发射到父它自己的组件中每一个按钮:

Vue.component('btn',{ 
    template: `<div><button @click="showModal = true"><slot></slot></button> 
    <modal v-if="showModal">I am a modal for {{button}}</modal></div>`, 
    props: ['button'], 
    data(){ 
    return { 
     showModal: false 
    } 
    } 
}); 

 

而这里的updated JSBin

如果你需要不同的情态动词对于每种按钮类型,则只需创建两个按钮组件edit-button,delete-button

您可能需要更多以数据为中心的应用程序蟑螂对你正在尝试。喜欢的东西,

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

然后,您可以还与通过prop