前言
前段时间热门文章有一篇跨页勾选,点进去大致看了下,看到评论说跨页勾选需求就不应该做,内心十分赞同。没想到自己就碰到了这个需求,人总是向现实低头,产品要求只能实现,本节就来介绍一下我的实现思路。
实现
跨页勾选的效果很简单,就是将每页的数据保存起来,并且在切换页码时能否回显之前勾选的数据,公司技术栈为vue2+element,我们就以此为准,其他技术栈都是类似思路。既然我们用了ui库,那么我们优先通过组件自带的属性方法完成此功能。
el-table
el-table是element的表格,默认是没有勾选的,利用selection在表格最前面添加多选框,并且配合selection-change事件使用:
js
<el-table
:data="list"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="姓名" prop="name">
</el-table-column>
</el-table>
selection-change事件的参数就是勾选行的数组,如果只是单页勾选,我们的功能就完成了。当数据过多加上分页,当我们改变页码的时候,数据更新,再勾选,此时selection-change返回的数据仅仅是当前页的,之前勾选完全没保存,并且当我们在返回之前的页码,勾选项也都会取消。针对勾选项回显,el-table-column刚好有相关的属性:
我们将reserve-selection设置为true,注意我们一定要添加row-key属性,row-key就是行数据的唯一标识。
js
<el-table row-key="id">
<el-table-column type="selection" reserve-selection width="55" />
事件
到此,就剩下最关键的一步,将数据处理。数据处理也很简单,就是筛选 。上面提到了selection-change返回的是当前页选中行的数据,我们将每页的数据都保存到一个数组,然后进去去重,过滤等处理就能实现得到真正的数据。selection-change每次返回的都是数组,处理起来可能相对复杂点,所以我们用select 、select-all替代selection-change。
- select:行内多选框状态变化时触发的事件,有两个参数selection(勾选的行数组),row(发生变化行的数据)。
- select-all:全选多选框变化时触发的事件,也就是表头的多选框,该事件只有一个参数selection。
下面开始我们的实现:
- 声明一个空数组multipleSelection,并且绑定上面两个事件。
js
<el-table
@select='rowSelect'
@select-all="selectAll"
>
2.当勾选单个数据时,触发select,我们通过selection中是否包含row判断当前行是选中还是取消,如果选中就用unshift添加到数组中,如果是取消就将该行从数组用splice方法删除,splice需要知道下标位置,这里我们用findIndex方法获取下标。我们假设行数据唯一标识为id,然后写出rowSelect。
3.全选多选框有三种状态,全选,半选,取消,重点考虑半选状态,半选也就是说有某些行已经选过了,此时再全选就有两种思路:
- 将数据全部添加到数组然后去重。
- 获取未被单独勾选的添加到数组。
刚好最近学习lodash源码库,这里我们借助lodash库用第二种方式实现,里面有一个lodash.differenceBy方法,可以让我们获取到未被勾选的单独数据,并且该方法也能兼容全选。最后取消,我们就用filter过滤掉当前list的数据。
这样我们单独勾选与全选,multipleSelection都会进行添加与删除,并且不会重复与遗漏,我们能够随意的跨页勾选。
总结
以上就跨页勾选的实现过程,整体实现还是很简单的,主要就是数据的处理,借助lodash库也提高了我们的效率。我们也可以在此基础上进行优化,比如添加row-click事件,当行选中联动前面的多选框进行勾选。