使用 Salesforce 数据 — LWC Data Access 完全指南

全面掌握 LWC 数据访问体系。涵盖四层方案选择(基础组件→LDS wire→GraphQL→Apex)、数据指南与决策路径、Lightning Data Service 共享缓存与变更检测机制(缓存失效/性能优化/UI API 基础)、record-form/view-form/edit-form 三组件功能对比表、加载记录(三种方式——record-form/view-form/getRecord+父记录)、编辑记录(自定义布局/四个事件/重置/自定义验证)、创建记录(预填充/Cancel 按钮)、命令式 createRecord/updateRecord/deleteRecord 完整示例。...

📅 2026/7/19 ✍️ ponybai 🏷️ lwc, salesforce, data

使用 Salesforce 数据

使用 Salesforce 数据

Salesforce 提供从简单到定制的多层数据访问方案。始终从最简单的方案开始,按需升级:① 基础组件(lightning-record-*form)→ ② LDS wire adapters(getRecord/getRecords/GraphQL)→ ③ Apex(最大灵活性)。LDS 支持所有自定义对象和 UI API 标准对象(不支持自定义元数据类型),不消耗 API 调用但受记录返回数量等通用限制。

数据指南 —— 选择正确的方案

数据指南

基础组件(最简单):lightning-record-form——一条语句完成查看/编辑/创建,自动切换模式,使用对象默认布局。指定字段而非布局以获得更好性能。需要自定义布局时用 lightning-record-view-form/lightning-record-edit-form

LDS Wire Adapters(中等灵活性):@wire 响应式提供数据——数据变更时自动更新组件。GraphQL wire adapter(lightning/graphql)可一次发送多个查询、跨对象查询、父子关系、过滤排序、动态 ID、变更操作,减少请求次数。命令式函数(createRecord/updateRecord/deleteRecord)仅在调用时执行——用于响应用户操作。

Apex(最大灵活性):当 LDS 不支持所需对象或操作时使用——如批量事务、Task/Event 对象。与 LDS 数据不同,Apex 数据不受管理——必须手动刷新(refreshApex() 用于 wire provision 的数据,命令式调用后需 notifyRecordUpdateAvailable() 更新 LDS 缓存)。

重要:Apex 和 LDS 不共享数据缓存——混用可能导致数据不一致。用 SOQL 获取数据时,建议获取和搜索都用 GraphQL wire adapter 以避免 null 值问题。

Lightning Data Service —— 共享缓存与变更检测

LDS 共享缓存

LDS 是 Salesforce 数据访问的核心基础设施——加载的记录被缓存并在组件间共享。同一记录无论被多少组件使用,只加载一次——显著提升性能。任何组件修改记录后,所有使用相关 @wire adapter 的组件都收到新值。

变更检测触发条件

  1. LWC 组件修改了记录
  2. LDS 缓存条目过期 + 组件的 @wire 触发读取(同浏览器、同应用、同用户)

LDS 性能优化

  • 渐进加载记录数据
  • 客户端缓存结果——从缓存加载比从服务器请求更快
  • 当依赖的 Salesforce 数据和元数据变更时失效缓存
  • 批量化和去重服务器调用
  • 对象和布局元数据有独立超时——存储在持久存储中。布局变更不会立即出现——重新登录或等待超时后刷新

LDS 构建在 User Interface API 之上——响应遵循 CRUD 访问、FLS 设置和共享规则,管理员的布局变更自动反映在响应中。

性能提示:使用返回最少数据的 wire adapter。GraphQL 只返回查询的字段;getRecord 额外返回子关系和布局类型。

比较基础组件 —— 记录表单

比较基础组件
功能record-formrecord-view-formrecord-edit-form
创建/编辑/查看记录仅查看创建+编辑
布局类型✅(Full/Compact)
多列布局
自定义字段布局✅(output-field)✅(input-field)
自定义记录数据渲染✅(含 getRecord)
自动模式切换✅(查看↔编辑)

选择指南:大多数场景从 record-form 开始——一条语句覆盖创建/编辑/查看。需要自定义字段布局和渲染时用 view-form/edit-form。需要完全自定义 UI 时用 wire adapters 或 Apex。始终尽量指定字段而非布局——指定布局只有在需要管理员(而非组件)控制字段时才用,且组件必须能处理布局中的每个字段。

加载记录 —— record-form 与 view-form

加载记录

record-form(最简单——两种模式)

<lightning-record-form record-id={recordId} object-api-name={objectApiName}
    fields={fields}></lightning-record-form>
// fields = ["AccountId", "Name", "Title", "Phone", "Email"];

// View 模式(默认——有 recordId):显示 output fields + 编辑图标
// Read-only 模式:仅 output fields,无编辑图标/按钮

record-view-form(自定义布局)

<lightning-record-view-form record-id={recordId} object-api-name="Account">
  <div class="slds-grid">
    <div class="slds-col slds-size_1-of-2">
      <lightning-output-field field-name="Name"></>
      <lightning-output-field field-name="Phone"></>
    </div>
  </div>
</lightning-record-view-form>

getRecord 自定义 UI

@wire(getRecord, { recordId: "$recordId", fields: [NAME_FIELD] }) record;
get nameValue() { return this.record.data ? getFieldValue(this.record.data, NAME_FIELD) : ""; }

<lightning-formatted-text value={nameValue}></lightning-formatted-text>
<!-- 父记录字段:import ... from "@salesforce/schema/Account.Owner.Email" -->

编辑记录 —— record-form 自定义布局与验证

编辑记录

record-form 编辑模式:mode="edit" + layout-type="Compact",或指定具体字段数组。推荐用 @salesforce/schema 导入字段引用(编译时验证)。

自定义布局与验证

record-edit-form 自定义布局:lightning-input-field 自动根据字段类型渲染输入控件。包含 lightning-messages 自动显示错误。四个自定义事件:error(服务器端错误)、load(数据加载)、submit(表单提交)、success(保存成功)。

重置表单:this.template.querySelectorAll("lightning-input-field").forEach(f => f.reset())

自定义验证:lightning-input-field 不支持客户端自定义验证——需要时用 lightning-input + setCustomValidity() + reportValidity()。在 onsubmit 中阻止默认行为→验证→通过则调用 this.template.querySelector("lightning-record-edit-form").submit(fields)

创建记录 —— 基础组件与预填充

创建记录

record-form 创建模式:不传 record-id——组件自动切换到创建模式。

<lightning-record-form object-api-name={accountObject} fields={myFields}
    onsuccess={handleAccountCreated}></lightning-record-form>
// myFields = [NAME_FIELD, WEBSITE_FIELD];  // @salesforce/schema 导入

record-edit-form 预填充:value 属性预设字段值——静态值直接在标记中,动态值通过 JS 属性绑定(value={myValue})。

构建自定义 UI —— 命令式 createRecord

命令式 createRecord

lightning-record*form 不够灵活时,使用 lightning/uiRecordApi 命令式函数:

import { createRecord } from "lightning/uiRecordApi";
import ACCOUNT_OBJECT from "@salesforce/schema/Account";
import NAME_FIELD from "@salesforce/schema/Account.Name";

async createAccount() {
  const fields = {};
  fields[NAME_FIELD.fieldApiName] = this.name;
  const recordInput = { apiName: ACCOUNT_OBJECT.objectApiName, fields };
  try {
    const account = await createRecord(recordInput);
    this.accountId = account.id;
    this.dispatchEvent(new ShowToastEvent({ title: 'Success', message: 'Account created', variant: 'success' }));
  } catch (error) {
    this.dispatchEvent(new ShowToastEvent({ title: 'Error', message: reduceErrors(error).join(', '), variant: 'error' }));
  }
}

关键要点:createRecord(recordInput) 返回 Promise——创建成功时解析为包含 account.id 的记录对象。② 使用 reduceErrors 工具函数从错误对象中提取可读错误消息(参考 lwc-recipes ldsUtils)。③ 同理 updateRecord(recordInput)deleteRecord(recordId) 用于更新和删除。④ 命令式调用是显式操作——不自动提供数据响应式更新。

感谢阅读本指南。如需继续学习,请参阅下一章:在表格中显示记录数据。