还记得同步请求下的原生table跨页勾选吗?

开头

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 + 三剑客)需要实现表格翻页勾选的功能,一个最直接明了的问题就是每次点击按钮提交表单,页面都会进行同步请求,从而返回新页面更新旧页面。

那么想要保留上一页的勾选结果,肯定需要借助本地缓存localStoragesessionStorage 都可以~ 这里使用的是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 Email
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~)~

相关推荐
uhakadotcom1 小时前
入门教程:如何编写一个chrome浏览器插件(以jobleap.cn收藏夹为例)
前端·javascript·面试
捡芝麻丢西瓜1 小时前
SPM 之 混编(OC、Swift)项目保姆级教程(Swift Package Manager)
前端
我是天龙_绍1 小时前
cdn是个啥?
前端
南雨北斗1 小时前
VSCode三个TS扩展工具介绍
前端
若无_1 小时前
了解 .husky:前端项目中的 Git Hooks 工具
前端·git
ze_juejin1 小时前
前端发送语音方式总结
前端
给月亮点灯|1 小时前
Vue3基础知识-Hook实现逻辑复用、代码解耦
前端·javascript·vue.js
Simon_He1 小时前
一款适用于 Vue 的高性能流式 Markdown 渲染器,源自我们的 AI 聊天机器人
前端·vue.js·markdown
顽强d石头1 小时前
v-model与.aync的区别
前端·javascript·vue.js
Hilaku1 小时前
我为什么认为 CSS-in-JS 是一个失败的技术?
前端·css·前端框架