table.set() 全局配置 response 字段映射须在首次 table.render() 前调用,仅影响后续新建表格;response 仅做字段名提取(大小写敏感、不支持嵌套路径),parseData 才是最终数据清洗入口,必须确保 count 为数字、data 为数组、code 为数值,并手动处理嵌套结构。

table.set() 全局配置 response 字段映射
必须在首次 table.render() 之前调用 table.set(),否则无效。它只影响之后新建的表格实例,已渲染的表格不会更新。
后端字段名和 response 配置必须完全一致(大小写敏感),比如后端返回 { status: 0, message: "", total: 100, records: [] },就得这么写:
layui.use('table', function(){
var table = layui.table;
table.set({
response: {
statusName: 'status',
msgName: 'message',
countName: 'total',
dataName: 'records'
}
});
});
-
statusName对应状态标识,Layui 内部会把它转成code;值为true/false时自动映射为0/1 -
countName必须是数字类型,字符串如"100"会导致分页按钮全部禁用,建议后续在parseData中用+res.total强转 -
dataName只做字段名提取,不处理嵌套结构,比如后端是{ data: { list: [...] } },dataName: 'data.list'是无效的——Layui 不支持点号路径
parseData 函数手动转换非标准结构
当后端返回嵌套过深、字段类型不对或需要逻辑判断时,response 映射无能为力,必须写 parseData。它在 response 映射之后执行,是最终的数据清洗入口。
常见错误:漏掉 count、返回 data 为 null 或 undefined、code 写成字符串。
假设后端返回:
{
"ok": true,
"error_msg": "success",
"pagination": { "total": 200 },
"result": { "items": [ {"id": 1, "user": {"name": "张三"}} ] }
}
对应 parseData 应该这样写:
parseData: function(res) {
return {
code: res.ok ? 0 : 1,
msg: res.error_msg || '',
count: Number(res.pagination?.total) || 0,
data: (res.result?.items || []).map(item => ({
id: item.id,
name: item.user?.name || ''
}))
};
}
-
count必须是数字,Number()或+强转不可省 -
data必须是数组,空数组[]安全,null或undefined会直接报Cannot read property 'length' of undefined - 多层嵌套必须手动
map扁平化,字段名要和列定义的field严格对齐
为什么改了 response 还是解析失败
因为 response 和 parseData 是两层逻辑:前者只做字段名提取,后者才真正决定最终输出结构。即使你配了 response,只要没写 parseData,Layui 仍会用内置默认函数处理提取后的结果——而这个默认函数依然要求 res.data 是数组、res.count 是数字。
典型陷阱:
- 后端返回
count: "200"→response提取后仍是字符串,分页失效 - 后端返回
data: null→response提取后是null,表格空白 - 后端返回
{ result: { list: [...] } }→response.dataName: 'result.list'不生效,必须靠parseData手动解构
所以,response 是简化版适配,parseData 是兜底方案,二者常需共存。
单表覆盖全局配置的写法
全局 table.set() 设好后,个别表格仍可单独覆盖,比如某个接口结构更怪,或需要加日志、过滤、格式化:
table.render({
elem: '#demo',
url: '/api/list',
parseData: function(res) {
console.log('原始响应:', res);
return {
code: res.code === 200 ? 0 : 1,
count: +res.meta?.total_count || 0,
data: (res.payload?.items || []).map(i => ({
...i,
apply_time: new Date(i.apply_time * 1000).toLocaleString()
}))
};
}
});
- 覆盖时不用重复写
response,它已在全局生效,res参数已是映射后的对象 - 若同时写了
response和parseData,parseData接收到的res是经过response提取后的版本 - 不要在
parseData里发请求、调用layer.msg或操作 DOM,它是纯同步数据转换函数
最易被忽略的是:count 类型校验在 2.8+ 版本变得更严格,字符串导致的分页失效往往没有明显报错,只能靠 Network 面板看响应体和 console.log 确认返回值类型。











