在表格中显示记录数据
使用 lightning-datatable 显示行列记录数据,lightning-tree-grid 显示层次结构数据(如 Account 及其关联的 Contacts——子记录通过切换按钮展开/折叠)。两者均不支持移动设备。本章涵盖内联编辑、自定义数据类型(扩展类 vs 插槽两种方式)、布局样式、编辑模板、无障碍和性能。
比较 Datatable 与 Tree-Grid + 层次表
| 功能 | datatable | tree-grid |
|---|---|---|
| 格式化列/自定义类型/行操作/调整列宽/行选择/换行裁剪/行号 | ✅ | ✅ |
| 列排序/内联编辑/无限滚动 | ✅ | ❌ |
| 可展开行(层次数据) | ❌ | ✅ |
Tree-Grid 层次表示例:Apex 返回 Account + 嵌套子查询 Cases → JS 中将 _children 键映射到子记录 → lightning-tree-grid 绑定 key-field="Id" + data={myData} + columns={columns}。每行级操作通过 onrowaction 处理——如用 NavigationMixin.Navigate 导航到编辑页面。支持 expandAll()/collapseAll() 公共方法。
内联编辑 —— 使用 updateRecord 基础实现
启用内联编辑需配置:key-field="Id" 关联行与记录、data 绑定数据、columns 定义列(含 editable: true)、onsave 处理器、draft-values 存储编辑值。Apex 方法用 @AuraEnabled(cacheable=true) + WITH USER_MODE。
// 列定义——editable:true 启用编辑
const COLS = [
{ label: "First Name", fieldName: FIRSTNAME_FIELD.fieldApiName, editable: true },
{ label: "Last Name", fieldName: LASTNAME_FIELD.fieldApiName, editable: true }, ...
];
async handleSave(event) {
const records = event.detail.draftValues.slice().map(draft => {
const fields = Object.assign({}, draft);
return { fields };
});
this.draftValues = []; // 清除草稿→隐藏 footer
const promises = records.map(record => updateRecord(record));
await Promise.all(promises); // 并行保存所有记录
await refreshApex(this.contacts); // 刷新数据
}
编辑后 Tab/点击外部 = footer 出现 Cancel+Save。草稿值格式:[{FirstName:"Sean", Id:"003..."}, ...]——包含编辑字段值和记录 ID。
内联编辑 —— 使用 Apex 批量更新
批量更新推荐单个事务用 Apex:编辑值传给 Apex controller → update DML。由于 Apex 更新不经过 LDS,必须调用 notifyRecordUpdateAvailable(recordIds) 刷新 LDS 缓存。
import updateContacts from "@salesforce/apex/ContactController.updateContacts";
import { notifyRecordUpdateAvailable } from "lightning/uiRecordApi";
async handleSave(event) {
const updatedFields = event.detail.draftValues;
const notifyChangeIds = updatedFields.map(row => ({ recordId: row.Id }));
await updateContacts({ data: updatedFields }); // Apex DML
notifyRecordUpdateAvailable(notifyChangeIds); // 通知 LDS 缓存失效
await refreshApex(this.contacts); // 刷新 wire
this.draftValues = [];
}
// Apex 控制器:JSON.deserialize → update DML
自定义数据类型 —— 扩展 LightningDatatable
标准类型不满足需求时可创建自定义数据类型。标准类型:action/boolean/button/button-icon/currency/date/email/location/number/percent/phone/text/url。
方式一——扩展类:创建新组件继承 LightningDatatable,在 static customTypes 中定义:template(HTML 模板引用)、typeAttributes(传给模板的属性数组)、standardCellLayout(true=标准布局/支持无障碍和键盘导航)。
import LightningDatatable from "lightning/datatable";
export default class MyTable extends LightningDatatable {
static customTypes = {
customName: { template: customNameTemplate, standardCellLayout: true, typeAttributes: ["accountName"] },
customNumber: { template: customNumberTemplate, standardCellLayout: false, typeAttributes: ["status"] },
};
}
// 模板中用 {typeAttributes.accountName} 访问属性
// 用 {value} 访问当前单元格值
实现时创建包装组件包含扩展的 datatable,定义列(type: "customName"),获取数据并传给 data 属性。
自定义数据类型 —— Slot 动态加载
方式二——Slot:运行时根据上下文动态决定加载哪些自定义类型。创建数据提供器组件——不继承 LightningDatatable,用 @api getDataTypes() 返回类型定义:
// customProvider.js——不继承 LightningDatatable
export default class CustomProvider extends LightningElement {
@api getDataTypes() {
return { customPictureType: { template: ..., standardCellLayout: true, typeAttributes: ["pictureUrl"] } };
}
}
// 在 datatable 中通过 slot 传递
<lightning-datatable key-field="Id" data={contacts.data} columns={columns}>
<c-custom-provider slot="customdatatypes"></c-custom-provider>
</lightning-datatable>
初始化时可过滤列(去除动态类型),点击按钮→设置完整列数组→自定义类型列出现。使用 connectedCallback 时注意调用 super.connectedCallback()。自定义类型单元格内不能嵌套另一个 lightning-datatable。
自定义数据类型 —— 布局、样式与事件
标准 vs 空白布局:标准布局(standardCellLayout: true)分散内容、左对齐垂直居中、左右小间距、支持无障碍。空白布局(默认)无间距、不支持无障碍。
应用样式:所有行 → cellAttributes: { class: "slds-theme_shade" }。特定行 → class: { fieldName: 'industryClass' }(数据中动态赋值)。仅支持 SLDS 工具类,不支持自定义类。对齐:cellAttributes: { alignment: "right" }。文本换行/裁剪:slds-hyphenate/slds-truncate + wrapText/wrap-text-max-lines。
自定义事件:自定义类型中派发 new CustomEvent("photoclick", { bubbles:true, composed:true, detail:{...} }) → 父组件通过 onphotoclick 处理。自定义类型排序时 event.detail.fieldName 返回 undefined——需传入实际字段名。
使自定义数据类型可编辑
三步启用内联编辑:① 创建编辑模板(*Edit.html)——使用 lightning-input 组件;② 在类型定义中添加 editTemplate;③ 列定义设 editable: true。
// customNumberEdit.html——编辑模板
<lightning-input type="number" value={editedValue} label={columnLabel}
required={required} min={typeAttributes.min} data-inputable="true"></>
// 类型定义中加入 editTemplate
customNumber: { template: ..., editTemplate: customNumberEditTemplate,
standardCellLayout: true, typeAttributes: ["status", "min"] }
编辑模板支持属性:editedValue(当前值)、columnLabel、required、typeAttributes。无障碍:data-inputable="true" + standardCellLayout: true 启用操作/导航模式。验证:在子组件中暴露 validity() getter 和 showHelpMessageIfInvalid()。限制:仅支持单输入基础组件;不支持 lightning-input-field;服务器端验证规则暂不支持。
Datatable 无障碍 —— 导航与操作模式
Datatable 提供两种交互模式:导航模式(Tab 在单元格间移动)和操作模式(Enter/Space 进入——聚焦单元格内可操作元素)。自定义类型可编辑时需 data-inputable="true" + standardCellLayout: true 以支持这两种模式。Enter/Space → 进入操作模式 → 可编辑单元格被激活 → Tab 在可操作元素间移动。
性能、显示密度与注意事项
性能:大量数据时用无限滚动(enable-infinite-loading + loadmore 事件)而非一次性加载。指定字段而非布局以获得更好性能。避免在自定义类型中进行昂贵操作——计算逻辑尽量放在 getter 中利用缓存。
显示密度:支持 Comfy/Compact 两种密度——通过 default-compact 或父组件的 density setting 控制。
关键注意事项:① 仅桌面端(不支持移动设备);② 自定义类型列排序需手动传 fieldName;③ connectedCallback 中必须 super.connectedCallback();④ 不能嵌套 datatable;⑤ 仅支持 SLDS 工具类样式,不支持自定义 CSS 类;⑥ lightning-input-field 不能在 datatable 中使用。
感谢阅读本指南。如需继续学习,请参阅下一章:使用 Wire Service 获取数据。