iview table 中的checkbox 填坑

近期项目使用iView的Table组件及Checkbox选择框,目标是实现点击Shift连选。使用中发现iView存在一些问题,如设置_checked属性与选中状态的影响不一致,程序设置选中状态时部分事件不触发,调用toggleSelect函数后on-selection-change事件的selection数据有偏差等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期做的项目用到了iview的table组件,并且带有checkbox选择框。
这里写图片描述

实现目标:点击shift实现连选的功能
iview坑:
(1)给data设置_check的属性。 _checked属性会影响checkbox的选中状态。但是checkbox的选中状态不会影响_check 属性
(2)

iview 官方文档说:
@on-selection-change,只要选中项发生变化时就会触发,返回值为 selection,已选项。

实现效果并不是这样的,而是:
用程序设置_checked=true后,并不会触发该事件。也不会触发on-select-cancel 和on-select。只有通过鼠标再次点击checkbox,才会触发上述三项事件。虽然最后参数中的selection是正确的。

用程序切换某一行的选中状态,需要调用函数this.$refs.xxx.toggleSelect(i),调用该函数后,会触发on-select-cancel 、on-select、on-selection-change事件。但是在on-selection-change事件中得到的selection数据只有两条,第一下点击的元素和最后一下点击的元素。

用户选中了第一个和第四个,目标是1-4都选中。执行过程如下所示

        =====on-select======
            1
        =====on-selection-change=====
            1
        =====on-select=====
            1,4
(因为on-select的程序中有调用toggleSelect(i),所以以下四行是on-select函数内部调用两次toggleSelect的结果)
        =====on-select=====
            1,2,4
        =====on-selection-change=====
            1,2,4
        =====on-select=====
            1,2,3,4
        =====on-selection-change=====
            1,2,3,4

(on-select方法执行结束,再调用on-selection-change,所以导致on-selection-change最后的selection中只有两个选中的元素) 
        =====on-selection-change=====
            1,4

所以可以推理iview的执行过程如下:触发选中事件时,先调用on-select, 再调用on-selection-change。

### 实现多选和反选功能 为了实现在 Vue.js 和 iViewtable 组件中的多选和反选功能,可以采取以下方法: #### 数据存储策略 对于多选状态的保存,在页面切换时不丢失已选择的数据项,建议创建一个独立的状态管理对象 `selectedRows` 来记录所有被选中的行。每当用户选择了某一行或取消选择时更新此列表。 ```javascript data() { return { selectedRows: [], // 存储当前选中的行ID或其他唯一标识符 detailData: { vos: [] // 表格显示的数据源 } }; } ``` #### 自定义渲染器处理逻辑 通过自定义列模板的方式向每行添加复选框控件,并监听其变化事件以便同步到全局的选择集合中去[^1]。 ```html <template slot-scope="{ row, index }"> <Checkbox v-model="row._checked" @on-change="handleSelectionChange(index)"> </Checkbox> </template> ``` 当检测到单个选项改变时调用相应的方法来维护整个表格内的全选/部分选标志位以及具体哪些条目处于选定状态。 ```javascript methods: { handleSelectionChange(idx) { const item = this.detailData.vos[idx]; if (item._checked && !this.selectedRows.includes(item.id)) { this.$set(this.selectedRows, this.selectedRows.length, item.id); } else if (!item._checked){ let idIndex = this.selectedRows.indexOf(item.id); if(idIndex !== -1){ this.selectedRows.splice(idIndex, 1); } } // 更新全选按钮状态 updateSelectAllStatus(); }, updateSelectAllStatus(){ var allChecked = true; for(let i=0;i<this.detailData.vos.length;i++){ if(!this.detailData.vos[i]._checked){ allChecked=false;break; } } this.selectAll=allChecked; }, toggleAllSelection(status){ this.detailData.vos.forEach((item)=>{ this.$set(item,'_checked',status); }); status?this.selectedRows=this.getAllIds():this.selectedRows=[]; this.updateSelectAllStatus(); }, getAllIds(){ return this.detailData.vos.map(({id})=>id); } } ``` 上述代码片段展示了如何利用 `_checked` 属性标记每一行是否已被勾选,并且提供了两个辅助函数用于批量操作——即全部选中 (`toggleAllSelection(true)`) 或者清除所有选择(`toggleAllSelection(false)`)[^2]。 #### 页面加载完成后初始化已有选择 考虑到分页场景下的持久化需求,可以在请求新的一页之前先将现有的 `selectedRows` 发送到服务器端暂存起来;而在接收到新一批数据之后再依据这些 ID 列表恢复对应的 checkbox 状态。 ---
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值