Vue2+Bootstrap-Vue实现b-table每行点击编辑打开对应模态框的方案
最优实现方案
全局仅维护1个编辑模态框实例,点击行编辑按钮时传入当前行数据即可,既避免了多实例的性能损耗,也天然保证同一时间只会打开1个模态框。
你之前的代码存在两个核心问题:
- 把模态框嵌套在表格单元格模板中,表格有多少行就会渲染多少个模态框实例,资源浪费
- 所有模态框的id固定为
modal-1,id冲突导致点击无法正常触发显隐
第一步:修改父组件代码
<template> <div> <b-table class="text-center" striped hover :items="items" :bordered=tableBordered :fields=tableFields :label-sort-asc=tableLabelSortAsc> <template #cell(view)="data"> <a target="_blank" rel="noopener" class="no-link" :href="data.item.url"> <b-icon icon="eye-fill"/> </a> </template> <template #cell(edit)="data"> <!-- 给齿轮图标加点击事件,传入当前行数据 --> <b-icon icon="gear-fill" @click="openEditModal(data.item)" style="cursor: pointer"/> </template> </b-table> <!-- 模态框移到表格外,全局只渲染1次 --> <edit-info-modal v-model="isEditModalOpen" :current-row="currentEditRow" /> </div> </template> <script> import EditInfoModal from './EditInfoModal.vue'; import { BIcon } from 'bootstrap-vue'; export default { components: { 'b-icon': BIcon, 'edit-info-modal': EditInfoModal }, data() { return { tableBordered: true, tableLabelSortAsc: "", tableFields: [ { sortable: false, key: 'edit', label: 'edit' }, { sortable: true, key: 'comments', label: 'comments' }, { sortable: false, key: 'view', label: 'view' } ], items: [ { "comments": "test", "url": "some_url" } ], // 新增控制模态框的变量 isEditModalOpen: false, currentEditRow: {} } }, methods: { openEditModal(row) { this.currentEditRow = row this.isEditModalOpen = true } } } </script> <style scoped> div { margin: auto 0; width: 100%; } a.no-link { color: black; text-decoration: none; } a:hover.no-link { color: black; text-decoration: none; cursor: pointer; } </style>
第二步:修改EditInfoModal子组件代码
<template> <div> <!-- 用v-model绑定显隐,监听hide事件通知父组件更新状态 --> <b-modal v-model="innerVisible" title="编辑信息" @hide="handleClose" > <p class="my-4">当前编辑的行内容:{{currentRow}}</p> <!-- 这里放你的编辑表单内容 --> </b-modal> </div> </template> <script> import { BModal } from 'bootstrap-vue'; export default { props: { // 接收父组件的显隐控制 value: Boolean, // 接收当前编辑的行数据 currentRow: { type: Object, default: () => ({}) } }, components: { 'b-modal': BModal }, computed: { innerVisible: { get() { return this.value }, set(val) { this.$emit('input', val) } } }, methods: { handleClose() { this.innerVisible = false } } } </script> <style scoped> div { margin: auto 0; width: 100%; } </style>
内容的提问来源于stack exchange,提问作者vesii
相关产品推荐
相关产品推荐

