复用Vue组件中Bootstrap模态框修改数据仅首个生效如何解决
问题根源
核心是HTML id属性全局唯一的特性和Bootstrap原生模态框的触发逻辑冲突:
- 你在组件内把模态框的id写死为
test,触发按钮的data-target也固定指向#test - 当你复用多个该组件时,页面上会出现多个id为
test的DOM元素 - Bootstrap原生的
data-toggle="modal"逻辑在匹配目标元素时,只会找到第一个符合id的模态框,也就是说你点击任意组件的打开按钮,实际打开的都是第一个组件的模态框 - 你在模态框里点击按钮触发的永远是第一个组件的方法,所以只有第一个组件的
filter值会更新,看起来就像其他组件的数据绑定失效了
解决方案
给每个组件实例的模态框生成唯一id,动态绑定到触发按钮和模态框元素上即可。Vue的每个组件实例都自带唯一的内置属性_uid,可以直接用来生成唯一id。
修改后的组件代码
<template> <div class="container-fluid pageContent"> <!-- 原固定id改成class,避免重复 --> <button type="button" class="btn btn-primary" data-toggle="modal" :data-target="`#${modalId}`"> Launch demo modal </button> <!-- Modal 动态绑定id --> <div class="modal fade" :id="modalId" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> </div> <div class="modal-footer"> <button @click="filterHistory">Add</button> <button @click="closeFilter">Remove</button> </div> </div> </div> </div> <!-- Headline --> <h1>{{filter}}</h1> </div> </template> <script> export default { name: "Table", data() { return { filter: false, // 用组件内置uid生成唯一模态框id modalId: `test_modal_${this._uid}` } }, methods: { filterHistory() { this.filter = true }, closeFilter() { this.filter = false }, } } </script>
可选优化
如果不想依赖Bootstrap原生的DOM操作逻辑,可以选择使用适配Vue的Bootstrap组件库,完全用Vue的响应式状态控制模态框的显示隐藏,从根源上避免id冲突的问题。
内容的提问来源于stack exchange,提问作者egx
相关产品推荐
相关产品推荐

