开头
hello~ 大家好,很开心再次和大家分享开发遇到的点点滴滴。
el-table实现跨页勾选
众所周知,el-table
想要实现 table
的翻页勾选,只需要两行代码:
js
<el-table :data="tableData" row-key="id" @selection-change="handleSelectionChange">
<el-table-column type="selection" :reserve-selection="true">
</el-table-column>
</el-table>
非常简单 (不懂的同学快做笔记~)
但脱离el-table
的封装回到原生table
,我们该如何实现table
的跨页勾选呢
原生table实现跨页勾选
最近一个前后混合开发 的老项目(php
+ jq
+ 三剑客)需要实现表格翻页勾选的功能,一个最直接明了的问题就是每次点击按钮提交表单,页面都会进行同步请求,从而返回新页面更新旧页面。
那么想要保留上一页的勾选结果,肯定需要借助本地缓存 ,localStorage
和 sessionStorage
都可以~ 这里使用的是localStorage
,存的是(routerkey, cacheIdsList)
,这里因为我们回显勾选只需要用到id
,因此cacheIdsList
是勾选行id
而不是整行对象
先实现原生table,带上勾选框~
html
<table>
<thead>
<tr>
<th><input type="checkbox" id="selectAllId">全选</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox"></td>
<td>John Doe</td>
<td>johndoe@example.com</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Jane Smith</td>
<td>janesmith@example.com</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>MikeJohnson</td>
<td>mikejohnson@example.com</td>
</tr>
</tbody>
</table>
全选 | Name | |
---|---|---|
John Doe | johndoe@example.com | |
Jane Smith | janesmith@example.com | |
MikeJohnson | mikejohnson@example.com |
勾选框点击事件
之后给表格的勾选框都带上点击事件,我们先梳理梳理流程
- 获取本地缓存的所有被勾选的行 cache_checked_box
- 获取当前页所有行 current_page_box
- 可知其他页的勾选情况不变,但当前页点击情况改变,因此先将涉及当前页的行从cache_checked_box里去除
- 获取当前页所有被勾选的行id current_page_checked
- 这时候得到了其他页被勾选的id列表 + 当前页被勾选的id列表,直接合并 + 去重得到当前表格所有勾选的行
- 将表格所有页勾选的行id都缓存到本地
这里用了php
的好伙伴 jq
js
$(document).ready(function() {
initCheckEvent()
});
function initCheckEvent() {
$('[id^="tr_"]').each(function() {
$(this).click(function() {
// checkId指明选择框id
initCheckEvent(checkId, storageKey)
})
});
}
function initCheckEvent(checkId, storageKey){// checkId指明选择框id
// 1.获取本地缓存的所有被勾选的行
let cache_checked_box = localStorage.getItem(storageKey) || ""
// 2.获取当前页所有行
const current_page_box = getAllBox()
// 3.将涉及当前页的行从cache_checked_box里去除
cache_checked_box = cache_checked_box.split(',').filter(item => {
return !current_page_box.includes(item) && !!item
})
// 4.获取当前页所有被勾选的行
const current_page_checked = getCheckedBox(name)
// 5.得到当前表格所有勾选的行
const allChecked = [...new Set([...cache_checked_box, ...current_page_checked])]
// 6.将表格所有页勾选的行id都缓存到本地
setCheckedStorage(storageKey, allChecked)
}
这样分解步骤后是不是非常简单~
(单独判断当前勾选行状态也是可以的,但是结合全选,防抖逻辑繁琐,不如这个方案清晰简单粗暴)
点击事件加上防抖优化
js
function initCheckEvent() {
$('[id^="tr_"]').each(function() {
$(this).click(function() {
debounceClick(() => initCheckEvent(checkId, storageKey), 1000)
})
});
}
还不会防抖的 xd 建议先和我一起去 地摊炒粉 学习
回显表格勾选情况
当刷新页面,应该回显表格的勾选情况
步骤:
- 获取缓存的勾选行
- 遍历表格当前页 的行,判断当前行id是否存在在缓存行列表里
- 存在,打勾
- 显示勾选行的数目
javascript
$(document).ready(function() {
initCheckedBox()
});
function initCheckedBox() {
// 回显勾选
restoreChecked(checkId, storageKey)
// checked_num 用来显示当前勾选数
const checked_num = (localStorage.getItem(storageKey) || []).length
$('#checked_num').text(checked_num)
}
function restoreChecked(checkId, storageKey) {
let cache_checked_box = localStorage.getItem(storageKey)
if(!cache_checked_box) return []
cache_checked_box = cache_checked_box.split(',')
$(`input[name="${checkId}"]`).each(function() {
if(cache_checked_box.includes($(this).val())){
$(this).prop("checked", true);
}
});
return cache_checked_box
}
这里我其实想直接用 restoreChecked(checkId, storageKey).length
而不是在重新调用 localStorage
, 因为已经获取到这个数据了,但为了 该死的 职责单一原则,又重新写一遍QWQ
如果是你,你会怎么写?
当页全选
- 判断一下全选框的状态
- 然后对当前页每一行进行勾选处理
- 最后用debounceFunc将勾选情况缓存到本地
html
<thead>
<tr>
<th>
<input type="checkbox"
id="selectAllId"
onclick="selectallBtn('tr_', 'selectAllId', () => debounceFunc());">
全选
</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
js
const debounceFunc = debounceClick(() => initCheckEvent(checkId, storageKey), 1000)
function selectallBtn(checkId, selectAllId = 'check_box', callback) {
const isChecked = $("#"+selectAllId).prop("checked")
$("#"+selectAllId).prop("checked", !isChecked)
$(`[id^=${checkId}]`).each(function() {
$(this).prop("checked", isChecked)
}
callback && callback()
}
清除本地缓存
天下没有不散的宴席,那天我留下了你,如今是时候...
不好意思,走错频道了QWQ
至于何时抛弃缓存结果,是走是留还得听产品的
产品希望缓存结果要么用户手动清除,要么当天23:59:59自动清除 步骤:
- 当天23:59:59过后,再次刷新页面(请求表格)前检查并删除缓存
- 手动点击取消勾选按钮
- 清理localStorage
- 将全选按钮设置未勾选
- 触发取消全选函数
- 清除所有勾选
- 展示勾选数设为0
js
$(document).ready(function() {
checkCacheTime(storageKey)
});
// 点击事件里设置缓存
function setCheckedStorage(storageKey, allChecked){
localStorage.setItem(storageKey, allChecked.join(','))
const cacheTime = new Date().setHours(23, 59, 59, 0);
localStorage.setItem(`${storageKey}-time`, cacheTime)
}
// 检查是否过期
function checkCacheTime(storageKey) {
const cacheTime = localStorage.getItem(`${storageKey}-time`)
const now = new Date().getTime()
if(now > cacheTime) localStorage.removeItem(storageKey)
}
// 取消勾选按钮
function cancelChecked() {
clearCache()
clearChecked()
$('#checked_num').text(0)
}
function clearCache() {
localStorage.removeItem(storageKey)
localStorage.removeItem(`${storageKey}-time`)
}
function clearChecked() {
$("#check_box").prop("checked", false)
selectall()
}
// 取消全选
function selectall(checkId, selectAllId = 'check_box') {
const isChecked = $("#"+selectAllId).prop("checked")
$(`[id^=${checkId}]`).each(function() {
$(this).prop("checked", isChecked)
}
}
这里的交互还是比较粗糙的(浅浅吐槽),可以多和产品拉扯拉扯
总结
总的,核心就是加三个入口函数
js
$(document).ready(function() {
checkCacheTime(storageKey)//检查缓存是否过期
initCheckedBox()//回显缓存勾选
initCheckEvent()//初始化选中框点击事件
});
const debounceFunc = debounceClick(() => initCheckEvent(checkId, storageKey), 1000)
function initCheckEvent() {
$('[id^="tr_"]').each(function() {
$(this).click(function() {
debounceFunc()
})
});
}
...
el-table
如何实现跨页勾选- 同步请求下的原生
table
勾选- html实现
- table里的选择框点击事件
- 点击优化 - 防抖
- 勾选回显
- 全部/取消勾选
- 清除勾选缓存
以上就是同步请求下表格跨页勾选的主要内容了,还有一小部分函数(Dom操作),相信大家都能轻松实现就不写了 (懒的)
如果喜欢这篇文章,可以点赞收藏关注我哦(wink~)~