3.2 table 与 form 心得:最常用的两大件
table:方法渲染为主,模板列解复杂单元格
table 支持方法渲染与自动渲染两种方式。自动渲染省事,靠页面上的属性声明就能跑起来;但项目稍复杂我就统一改用方法渲染,理由有三:配置集中在 JS 里便于维护,列结构可以按接口返回动态拼装,渲染时机完全可控。
方法渲染的骨架大致是(以官方文档为准):
table.render({
elem: "#demo",
url: "/api/list",
page: true
});
一行声明容器、数据源与分页,其余细节全在配置里生长,这正是方法渲染可维护性的来源。自动渲染我留给了静态演示页和快速原型,正式项目一律方法渲染。
cols 列配置是 table 的灵魂,我把高频用法汇总如下:
| 配置 | 用途 | 注意 |
|---|---|---|
| 模板列 | 自定义单元格内容 | 输出 HTML 字符串,注意转义 |
| toolbar | 表头工具条与操作按钮 | 事件监听与模板配合使用 |
| 排序 | 列头点击排序 | 前端排序与后端排序行为不同 |
| 分页 | 数据分页 | 大数据量必须配合后端分页 |
| 筛选 | 列显示隐藏 | 列多时是提升体验的小利器 |
模板列是我处理复杂单元格的首选:状态徽标、行内操作按钮、两行摘要,都写进模板里返回拼好的 HTML。写的时候要养成转义习惯,用户输入的内容直接拼进 HTML 有 XSS 风险,别省这一步。
大数据量:分页参数与 URL 模式
数据量一大,table 的表现完全取决于分页策略。我的原则是:超过几百行就交给后端分页,前端只渲染当前页,分页参数随请求走,绝不整表拉回前端。URL 模式下分页状态保留在地址里,刷新、回退、分享链接都不丢页码,排查问题时还能直接复现现场,这对维护者是实打实的福利。
几条分页心得:
- 页码与每页条数交给组件维护,请求里按文档约定的参数名传给后端,前后端口径统一;
- 每页条数的默认值别拍脑袋,结合列宽与常用屏幕高度定一个舒服的值;
- 排序、筛选触发重载时保持分页参数语义一致,避免页码与数据错位;
- 后端分页是原则,前端一次性渲染上千行属于例外,例外要有明确理由。
2.12 的 ajax 自定义请求:统一拦截器项目的福音
2.12 新增了 ajax 自定义请求选项。它解决的是老项目里最常见的别扭:页面通常有一套统一的请求层,自动带 token、统一处理错误码、统一 loading,而表格自己发请求就绕开了这套管道,鉴权头和错误提示都得二次实现。有了 ajax 选项,表格请求可以直接接入项目统一的请求体系,前后行为终于一致。
另外 2.12 还带来了 syncFixedRowHeight,涉及固定列与行高同步的场景在高版本下表现更稳。具体参数与取值以官方文档为准。
form:动态 DOM 之后必须 form.render()
form 的自动渲染依赖 class 声明,页面静态写好的表单打开就能用。但只要在运行时动态插入 DOM——比如请求接口后填充 select 的选项——就必须手动调用 form.render() 重绘,否则页面上要么一片空白,要么还是原生控件。这是我见过最高频的失灵原因,没有之一。
事件监听用 form.on,按 filter 分流:
form.on("submit(demo-filter)", function(data){
// 只响应 filter 为 demo-filter 的提交
return false;
});
filter 分流的好处是同一页多个表单互不干扰,监听代码可以分散到各业务模块,不必全局判别是谁触发的。
再补两条小经验:form.render() 可以按类型、按局部容器重绘,不必每次全量刷新,动态内容多的时候能省下不少开销;select 的搜索配置在选项几十个以上时几乎是刚需,开启后用户直接键入即可过滤,体验差距一目了然,具体属性名以官方文档为准。
form 常见失灵速查
| 失灵现象 | 原因 | 处方 |
|---|---|---|
| select 动态填充后不生效 | 未重绘 | 插入 DOM 后调用 form.render() |
| checkbox 点了没反应 | 元素是动态生成的 | 同样重绘对应类型 |
| 监听一直不触发 | filter 不匹配 | 核对属性值与 form.on 参数 |
| 提交拿不到表单值 | 未走 form 提交机制 | 从提交回调的 data 字段取值 |
select 还支持搜索配置,选项较多时开启搜索能明显改善体验,具体属性名以官方文档为准。
