Vue+BootstrapVue b-table仅首页可删除及分页显示异常问题
问题根因
- 初始删除操作错位的原因:
b-table开启内置分页功能时,作用域插槽返回的data.index是当前页面内的相对索引,不是全量数据源的绝对索引。例如第二页的第一条数据的data.index为0,直接传值删除会定位到全量数组的第0位,也就是第一页的第一条数据。 - 手动切分数据后非第一页空白的原因:你同时开启了
b-table的内置分页(传入了per-page、current-page属性),又提前把items切为了仅包含当前页数据的数组,b-table会对传入的单页数据再次做分页截断,跳转到第二页时自然取不到内容。同时b-pagination的total-rows绑定了切分后的items长度(最大为5),也会导致分页页数计算错误。
解决方案
推荐使用b-table内置分页方案,改动最小且符合组件设计逻辑:
步骤1:修正删除逻辑的索引计算
不要直接使用插槽返回的相对索引,要结合当前页码计算全量数据的绝对索引,更推荐直接使用条目的唯一ID做删除标识,避免数组顺序变动导致的定位错误。
步骤2:修正分页组件的总条目绑定
b-pagination的total-rows要绑定全量数据源的长度,不要绑定切分后的items长度。
步骤3:恢复全量items计算逻辑
不需要自己切分数据,直接返回全量数组交由b-table内置分页处理。
修正后代码
模板部分
<b-table id="traffic-routes" :fields="fieldsForTrafficRoutes" :items="itemsForTrafficRoutes" :per-page="perPageForTrafficRoutes" :current-page="currentPageForTrafficRoutes" > <template v-slot:cell(action)="data"> <div class="d-flex align-items-center justify-content-end"> <!-- 方式1:计算绝对索引删除 --> <a class="action-icon mr-2" @click="removeRow((currentPageForTrafficRoutes - 1) * perPageForTrafficRoutes + data.index)" > Delete </a> <!-- 方式2(更推荐):用条目唯一ID删除 --> <!-- <a class="action-icon mr-2" @click="removeRow(data.item.id)" > Delete </a> --> </div> </template> </b-table> <b-pagination v-model="currentPageForTrafficRoutes" aria-controls="traffic-routes" align="right" :total-rows="getAllTrafficRoutes?.length || 0" :per-page="perPageForTrafficRoutes" ></b-pagination>
JS逻辑部分
export default { data() { return { perPageForTrafficRoutes: 5, currentPageForTrafficRoutes: 1, // ... } }, computed: { ...mapGetters([ 'getAllTrafficRoutes', ]), itemsForTrafficRoutes() { // 直接返回全量数据,交由b-table做内置分页 return JSON.parse(JSON.stringify(this.getAllTrafficRoutes)); }, }, methods: { // 方式1对应的删除方法 removeRow(absoluteIndex) { const updatedList = this.getAllTrafficRoutes.filter((_, index) => index !== absoluteIndex) // 把更新后的数组提交到vuex存储即可 // 补充:如果删除后当前页无数据,自动回退到上一页 if (updatedList.length <= (this.currentPageForTrafficRoutes - 1) * this.perPageForTrafficRoutes && this.currentPageForTrafficRoutes > 1) { this.currentPageForTrafficRoutes-- } }, // 方式2对应的删除方法 // removeRow(id) { // const updatedList = this.getAllTrafficRoutes.filter(item => item.id !== id) // // 提交更新到vuex // if (updatedList.length <= (this.currentPageForTrafficRoutes - 1) * this.perPageForTrafficRoutes && this.currentPageForTrafficRoutes > 1) { // this.currentPageForTrafficRoutes-- // } // } } }
内容的提问来源于stack exchange,提问作者Peoray
相关产品推荐
相关产品推荐

