导航到页面、记录和列表

要在 Lightning Experience、Experience Builder 站点和 Salesforce 移动应用程序中导航,请使用导航服务 .lightning/navigation

该服务仅在 Lightning Experience、Experience Builder 站点和 Salesforce 移动应用程序中受支持。其他容器不支持它,例如 Lightning Components for Visualforce 或 Lightning Out。即使您在 Lightning Experience 或 Salesforce 移动应用程序中访问这些容器,也是如此。lightning/navigation

基本导航

使用导航服务 导航到许多不同的页面类型,如记录、列表视图和对象。还可以使用导航服务打开文件。lightning/navigation

导航服务使用 .PageReference 是一个 JavaScript 对象,用于描述页面类型、其属性和页面状态。使用 a 可以使组件免受将来对 URL 格式的更改的影响。它还允许您的组件在多个应用程序中使用,每个应用程序都可以使用不同的 URL 格式。PageReferencePageReference

PageReference财产类型描述必填
type字符串要在 Lightning Experience、Experience Builder 站点或 Salesforce 移动应用程序中导航,请定义一个对象。该类型生成唯一的 URL 格式,并定义应用于该类型的所有页面的属性。对于 Experience Builder 站点,根据页面类型,LWR 站点和 Aura 站点之间的属性要求可能有所不同。请参见 PageReference 类型。PageReferencePageReferencePageReference是的
attributes对象确定目标页面的名称/值对的映射。页面类型定义可能的属性名称集及其各自的值类型。是的
state对象一组具有字符串键和字符串值的键值对。这些参数有条件地自定义给定页面中的内容。某些页面引用类型支持一组标准属性。还可以将非标准属性传递到只要它们具有命名空间即可。statestate

导航服务将两个 API 添加到组件的类中。由于这些 API 是类上的方法,因此请从 调用它们。this

  • [NavigationMixin.Navigate](pageReference, [replace])组件调用以导航到应用程序中的另一个页面。this[NavigationMixin.Navigate]
  • [NavigationMixin.GenerateUrl](pageReference)组件调用以获取解析为生成的 URL 的 URL。该组件可以在定位点的属性中使用 URL。它还可以使用 URL 通过浏览器 API 打开新窗口。this[NavigationMixin.GenerateUrl]promisehrefwindow.open({url})

使用导航服务

  1. 在组件的 JavaScript 类中,从 lightning/navigation 模块导入函数。NavigationMixinimport { NavigationMixin } from "lightning/navigation";
  2. 将该函数应用于组件的基类。NavigationMixinexport default class MyCustomElement extends NavigationMixin(LightningElement) {}
  3. 创建一个用于定义页面的纯 JavaScript PageReference 对象。
  4. 若要调度导航请求,请调用导航服务的函数。如果设置为 ,则替换浏览器历史记录中的现有条目,以便用户不必按两次后退按钮。缺省值为 。[NavigationMixin.Navigate]({pageReference}, [{replace}]){replace}true{pageReference}falsenavigateNext() { this[NavigationMixin.Navigate]({ type: 'standard__navItemPage', attributes: { apiName: this.tabName, }, }); }

当您使用 导航到页面引用时,例如从启用了快速操作的组件,默认情况下不会自动关闭该模式。例如,如果组件导航到记录创建页面,则包含组件的模式将保持打开状态,但处于非活动状态,而另一个模式则将其与记录创建页面覆盖。当您使用记录创建页面关闭新模式时,包含组件的先前模式将再次变为活动状态。要在导航时自动关闭上一个模式,请设置为 。[NavigationMixin.Navigate](pageReference, [replace])replacetrue

示例:导航到帐户主页

此示例显示指向帐户主页的链接。当用户单击该链接时,事件处理程序 将调用导航服务的方法,该方法将加载帐户主页。帐户主页 URL 也可在锚标记中找到,该标记允许用户复制链接或在新窗口中打开它。clickhandleClickNavigate

<!-- navigationLinkExample.html -->
<template>
  <div>
    <a href={url} onclick={handleClick}>Account Home</a>
  </div>
</template>

在组件的 JavaScript 文件中,导入导航服务。

若要导航到帐户主页并生成其 URL,导航服务使用一个对象。当组件插入到 DOM 中时,对象 在生命周期钩子中定义。导航服务将帐户主页 URL 存储在模板中使用的属性中。PageReferencePageReferenceaccountHomePageRefconnectedCallback()url

事件处理程序也在组件的 JavaScript 类中定义,并导航到页面引用 .handleClickaccountHomePageRef

// navigationLinkExample.js
import { LightningElement, wire } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class NavigationLinkExample extends NavigationMixin(LightningElement) {
  url;

  connectedCallback() {
    // Store the PageReference in a variable to use in handleClick.
    // This is a plain Javascript object that conforms to the
    // PageReference type by including 'type' and 'attributes' properties.
    // The 'state' property is optional.
    this.accountHomePageRef = {
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Account",
        actionName: "home",
      },
    };
    this[NavigationMixin.GenerateUrl](this.accountHomePageRef).then((url) => (this.url = url));
  }

  handleClick(evt) {
    // Stop the event's default behavior.
    // Stop the event from bubbling up in the DOM.
    evt.preventDefault();
    evt.stopPropagation();
    // Navigate to the Account Home page.
    this[NavigationMixin.Navigate](this.accountHomePageRef);
  }
}

添加查询参数

若要向 URL 添加查询参数,请更新该属性。导航服务使用 a 来生成 URL。属性的键值对将序列化为 URL 查询参数。查询参数描述页面并形成用户可以保存或添加书签的更具体的 URL。PageReference.statePageReferencestate

使用 state 属性

使用属性时,请牢记这些行为。state

  • 对象已冻结,因此无法直接更改它。要导航到具有修改后的同一页面,请复制当前页面并使用 修改副本。PageReferencestatePageReferenceObject.assign({}, pageReference)
  • state属性必须使用命名空间前缀,后跟两个下划线。如果组件不是托管包的一部分,请使用命名空间前缀。如果组件是托管包的一部分,请使用包的命名空间。__c
  • 由于 的键值对序列化为 URL 查询参数,因此所有值都必须是字符串。PageReference.state
  • 使用值的代码必须将值分析为其正确的格式。state
  • 要从对象中删除值,请将其设置为 。stateundefined
  • 即使使用 HTTPS,在 URL 参数中包含个人数据也不安全。有关详细信息,请参阅存储敏感数据。
  • 在使用 Aura 或 LWR 模板构建的 Lightning Experience 和 Experience Builder 站点中,仅当 URL 查询字符串发生更改时,不会重新呈现视图。为了对 URL 查询字符串中的更改做出反应,我们建议组件观察该对象并与页面引用的 .CurrentPageReferencestate

示例:更新当前页面状态

此示例中的组件有一个标记为“显示面板”的链接,单击该链接时将更改为“隐藏面板”。单击任一链接都会更新当前页面的状态。当页面状态更改时,用 修饰的属性将更新。组件将重新呈现以显示或隐藏面板并更新链接标签。this.currentPageReference@wire(CurrentPageReference)

<!-- pageStateChangeExample.html -->
<template>
  <div>
    <a href={showPanelUrl} onclick={handleShowPanelClick}>Show Panel</a>
  </div>
  <div lwc:if={showPanel}>
    <h1>This is the panel</h1>
    <a href={noPanelUrl} onclick={handleNoPanelClick}>Hide Panel</a>
  </div>
</template>
// pageStateChangeExample.js
import { LightningElement, wire } from "lwc";
import { CurrentPageReference, NavigationMixin } from "lightning/navigation";

export default class PageStateChangeExample extends NavigationMixin(LightningElement) {
  // Declare the currentPageReference variable in order to track it
  currentPageReference;
  // Injects the page reference that describes the current page
  @wire(CurrentPageReference)
  setCurrentPageReference(currentPageReference) {
    this.currentPageReference = currentPageReference;

    if (this.connected) {
      // We need to have the currentPageReference, and to be connected before
      // we can use NavigationMixin
      this.generateUrls();
    } else {
      // NavigationMixin doesn't work before connectedCallback, so if we have
      // the currentPageReference, but haven't connected yet, queue it up
      this.generateUrlOnConnected = true;
    }
  }

  showPanelUrl;
  noPanelUrl;

  // Determines the display for the component's panel
  get showPanel() {
    // Derive this property's value from the current page state
    return this.currentPageReference && this.currentPageReference.state.c__showPanel == "true";
  }

  generateUrls() {
    this[NavigationMixin.GenerateUrl](this.showPanelPageReference).then(
      (url) => (this.showPanelUrl = url),
    );
    this[NavigationMixin.GenerateUrl](this.noPanelPageReference).then(
      (url) => (this.noPanelUrl = url),
    );
  }

  // Returns a page reference that matches the current page
  // but sets the 'c__showPanel' page state property to 'true'
  get showPanelPageReference() {
    return this.getUpdatedPageReference({
      c__showPanel: "true", // Value must be a string
    });
  }

  // Returns a page reference that matches the current page
  // but removes the 'c__showPanel' page state property
  get noPanelPageReference() {
    return this.getUpdatedPageReference({
      // Removes this property from the state
      c__showPanel: undefined,
    });
  }

  // Utility function that returns a copy of the current page reference
  // after applying the stateChanges to the state on the new copy
  getUpdatedPageReference(stateChanges) {
    // The currentPageReference property is read-only.
    // To navigate to the same page with a modified state,
    // copy the currentPageReference and modify the copy.
    return Object.assign({}, this.currentPageReference, {
      // Copy the existing page state to preserve other parameters
      // If any property on stateChanges is present but has an undefined
      // value, that property in the page state is removed.
      state: Object.assign({}, this.currentPageReference.state, stateChanges),
    });
  }

  connectedCallback() {
    this.connected = true;

    // If the CurrentPageReference returned before this component was connected,
    // we can use NavigationMixin to generate the URLs
    if (this.generateUrlOnConnected) {
      this.generateUrls();
    }
  }

  handleShowPanelClick(evt) {
    evt.preventDefault();
    evt.stopPropagation();
    // This example passes true to the 'replace' argument on the navigate API
    // to change the page state without pushing a new history entry onto the
    // browser history stack. This prevents the user from having to press back
    // twice to return to the previous page.
    this[NavigationMixin.Navigate](this.showPanelPageReference, true);
  }

  handleNoPanelClick(evt) {
    evt.preventDefault();
    evt.stopPropagation();
    this[NavigationMixin.Navigate](this.noPanelPageReference, true);
  }
}

导航服务支持 Lightning 中不同类型的页面。每种类型都支持一组不同的特性和状态属性。这两个 API 都支持这些类型。PageReferencePageReference

示例:导航到页面

让我们看一个示例,说明如何创建导航到页面的按钮。

我们的示例有一个组件,它是 Salesforce 应用程序中的一个页面。在页面底部,有一个带有标签 Next 的组件。可以在每个页面的底部使用该组件,让用户浏览应用程序。welcomenavtabnavtab

<!-- welcome.html -->
<!-- lots and lots of code removed for brevity -->

<div class="slds-m-vertical_large">
  <c-navtab tab-name="lightning_components" label="Next"></c-navtab>
</div>

该组件自定义组件以导航到应用程序中的下一页。使用者指定 a 和 a 。c-nav-tablightning-buttontab-namelabel

<!-- navTab.html -->
<template>
  <lightning-button variant="brand" label={label} title={label} onclick={navigateNext}>
  </lightning-button>
</template>
// navTab.js
import { LightningElement, api } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class Navtab extends NavigationMixin(LightningElement) {
  @api tabName;
  @api label;
  navigateNext() {
    this[NavigationMixin.Navigate]({
      type: "standard__navItemPage",
      attributes: {
        apiName: this.tabName,
      },
    });
  }
}

提示

lwc-recipes 存储库有很多导航示例。查看名为 的组件。nav*

更多页面类型示例

此代码显示了在 Lightning 中导航到不同类型页面的示例。这些示例演示如何创建不同类型的页面引用对象并导航到这些页面。您还可以将页面引用传递给 API,以检索解析为页面的 URL。[NavigationMixin.GenerateUrl](pageReference)promise

// navigationToPagesExample.js
import { LightningElement, wire } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class NavigationToPagesExample extends NavigationMixin(LightningElement) {
  navigateToObjectHome() {
    // Navigate to the Case object home page.
    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Case",
        actionName: "home",
      },
    });
  }

  navigateToListView() {
    // Navigate to the Contact object's Recent list view.
    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Contact",
        actionName: "list",
      },
      state: {
        // 'filterName' is a property on the page 'state'
        // and identifies the target list view.
        // It may also be an 18 character list view id.
        filterName: "Recent", // or by 18 char '00BT0000002TONQMA4'
      },
    });
  }

  navigateToNewRecordPage() {
    // Opens the new Account record modal
    // to create an Account.
    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Account",
        actionName: "new",
      },
    });
  }

  navigateToRecordViewPage() {
    // View a custom object record.
    this[NavigationMixin.Navigate]({
      type: "standard__recordPage",
      attributes: {
        recordId: "a03B0000002tEurIAE",
        objectApiName: "namespace__ObjectName", // objectApiName is optional
        actionName: "view",
      },
    });
  }

  navigateToRecordEditPage() {
    // Opens the Account record modal
    // to view a particular record.
    this[NavigationMixin.Navigate]({
      type: "standard__recordPage",
      attributes: {
        recordId: "001B000000ZBz22IAD",
        objectApiName: "Account", // objectApiName is optional
        actionName: "edit",
      },
    });
  }

  navigateToRelatedList() {
    // Navigate to the CaseComments related list page
    // for a specific Case record.
    this[NavigationMixin.Navigate]({
      type: "standard__recordRelationshipPage",
      attributes: {
        recordId: "500xx000000Ykt4AAC",
        objectApiName: "Case",
        relationshipApiName: "CaseComments",
        actionName: "view",
      },
    });
  }

  navigateToTabPage() {
    // Navigate to a specific CustomTab.
    this[NavigationMixin.Navigate]({
      type: "standard__navItemPage",
      attributes: {
        // CustomTabs from managed packages are identified by their
        // namespace prefix followed by two underscores followed by the
        // developer name. E.g. 'namespace__TabName'
        apiName: "CustomTabName",
      },
    });
  }

  navigateToWebPage() {
    // Navigate to a URL
    this[NavigationMixin.Navigate](
      {
        type: "standard__webPage",
        attributes: {
          url: "http://salesforce.com",
        },
      },
      true, // Replaces the current page in your browser history with the URL
    );
  }
}

若要使用预填充的字段值启动记录的创建页面,请同时使用 and。lightning/pageReferenceUtilslightning/navigation

lightning/pageReferenceUtils 模块提供了 and 函数,用于将默认字段值编码为字符串并对其进行解码。将编码字符串分配给页面引用中的属性。encodeDefaultFieldValues()decodeDefaultFieldValues()pageReference.state.defaultFieldValuesstandard__objectPage

使用标准操作时,默认字段值会以字符串形式通过 URL 传递到对象,并为您处理重定向和替换。通过覆盖操作,您负责从 URL 解码默认字段值的字符串。

提示

在 lwc-recipes 示例存储库中,请参阅 navToNewRecordWithDefaults 组件。

使用标准操作启动具有默认字段值的联系人记录

此示例使用预填充的默认值启动记录的创建页。

此示例 HTML 包含用于创建联系人的链接。

<!-- navToNewRecordWithDefaults.html -->
<template>
  <lightning-button
    name="new-with-defaults"
    label="Go to New Contact with Defaults"
    class="slds-m-around_medium"
    onclick={navigateToNewContactWithDefaults}>
  </lightning-button>
</template>

要将默认字段值编码为字符串,请将它们传递给 。将编码的字符串分配给页面引用中的属性。encodeDefaultFieldValues()state.defaultFieldValues

// navToNewRecordWithDefaults.js
import { LightningElement } from "lwc";
import { NavigationMixin } from "lightning/navigation";
import { encodeDefaultFieldValues } from "lightning/pageReferenceUtils";

export default class NavToNewRecordWithDefaults extends NavigationMixin(LightningElement) {
  navigateToNewContactWithDefaults() {
    const defaultValues = encodeDefaultFieldValues({
      FirstName: "Morag",
      LastName: "de Fault",
      LeadSource: "Other",
    });

    console.log(defaultValues);

    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Contact",
        actionName: "new",
      },
      state: {
        defaultFieldValues: defaultValues,
      },
    });
  }
}

使用覆盖操作处理默认字段值

要使用自定义解决方案覆盖标准操作行为,请将模块包装在 Aura 组件中。

// auraOverrideWrapper.cmp
<aura:component implements="lightning:actionOverride">
  <c:lwcNewAccountOverride></c:lwcNewAccountOverride>
</aura:component>

该组件包括一个用于显示默认字段值的新客户记录页的窗体。lwcNewAccountOverride

<!-- lwcNewAccountOverride.html -->
<template>
  <lightning-record-edit-form object-api-name="Account" onsuccess={handleAccountCreated}>
    <lightning-input-field field-name="Name" value={dfv_AccountName}> </lightning-input-field>
    <lightning-input-field field-name="NumberOfEmployees" value={dfv_NumberOfEmployees}>
    </lightning-input-field>
    <lightning-input-field field-name="OwnerId" value={dfv_OwnerId}> </lightning-input-field>
    <lightning-input-field field-name="CustomCheckbox__c" value={dfv_CustomCheckbox}>
    </lightning-input-field>

    <lightning-button class="slds-m-top_small" type="submit" label="Create"> </lightning-button>
  </lightning-record-edit-form>
</template>

通过覆盖操作,您负责从 URL 解码默认字段值的字符串。

此示例用于从中读取默认字段值并获取编码的字符串。然后,它将字符串传递给 对其进行解码并处理帐户创建。CurrentPageReferencestatedecodeDefaultFieldValues()

此示例类似于使用 预填充字段值,不同之处在于此处的 是导航到表单时动态生成的。lightning-record-edit-formdefaultFieldValues

// lwcNewAccountOverride.js
import { LightningElement, wire } from "lwc";
import { CurrentPageReference } from "lightning/navigation";
import { decodeDefaultFieldValues } from "lightning/pageReferenceUtils";

export default class LwcNewAccountOverride extends LightningElement {
  @wire(CurrentPageReference)
  setCurrentPageReference(currentPageReference) {
    if (currentPageReference.state.defaultFieldValues) {
      const dfvObject = decodeDefaultFieldValues(currentPageReference.state.defaultFieldValues);
      this.dfv_AccountName = dfvObject.Name;
      this.dfv_NumberOfEmployees = dfvObject.NumberOfEmployees;
      // Handling required for boolean because we don't support boolean field types
      this.dfv_CustomCheckbox = dfvObject.CustomCheckbox__c === "true";
      this.dfv_OwnerId = dfvObject.OwnerId;
    }
  }

  dfv_AccountName = "";
  dfv_NumberOfEmployees = "";
  dfv_OwnerId = "";
  dfv_CustomCheckbox = false;

  // Run code when account is created
  handleAccountCreated() {}
}

重要

所有编码的默认字段值都以字符串形式传递到记录创建页面。例如,作为字符串而不是数字传递到页面中,布尔值 和 作为字符串传递。35000truefalse

若要使用此代码,请在“设置”中输入 。在 Account 对象上,创建一个具有 API 名称的复选框字段。然后选择“按钮”、“链接”和“操作”,并编辑“新建”操作。对于 Lightning Experience Override,选择 Lightning 组件,然后选择组件。Object ManagerCustomCheckbox__cc:auraOverrideWrapper

打开文件

要在 Lightning Experience 和 Salesforce 应用程序中打开一个或多个文件记录,请使用导航服务 .导航服务在 Lightning Experience 的模式对话框中打开一个或多个文件的预览,或在移动设备上的 Salesforce 应用程序中触发文件下载。lightning/navigation

使用页面引用打开文件

导航服务使用 PageReference,它描述一个页面,在本例中是一个文件。

使用带有 和 属性的页面引用。'type': 'standard__namedPage'pageNamefilePreview

命名页值支持 ContentDocument 和 ContentHubItem(外部文件)对象。Lightning Experience 和所有版本的移动应用程序都支持命名页面值。其他容器(例如 Lightning Components for Visualforce、Lightning Out 或 Experience Cloud 站点)不支持此功能。即使您在 Lightning Experience 或 Salesforce 移动应用程序中访问这些容器,页面值也不受支持。filePreviewfilePreview

示例:打开文件记录

此示例在 Lightning Experience 和 Salesforce 应用程序中打开带有 ID 的记录。069xx0000000001AAA

<!-- openFileSample.html -->
<template>
  <div>
    <a onclick={navigateToFiles}>Navigate To Files</a>
  </div>
</template>
// openFileSample.js
import { LightningElement } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class OpenFileSample extends NavigationMixin(LightningElement) {
  navigateToFiles() {
    this[NavigationMixin.Navigate]({
      type: "standard__namedPage",
      attributes: {
        pageName: "filePreview",
      },
      state: {
        recordIds: "069xx0000000001AAA,069xx000000000BAAQ",
        selectedRecordId: "069xx0000000001AAA",
      },
    });
  }
}

该属性是可供下载的所有记录 ID 的逗号分隔列表。recordIds

在 Lightning Experience 中,首先下载中指定的记录。用户可以通过单击应用程序中的箭头切换到其他记录。桌面文件预览器提供基于图像和 SVG 的多页办公文档预览、演示模式以及对文件操作(如共享、下载、上传和删除)的快速访问。selectedRecordId

在 Salesforce 应用程序中,触发事件时会下载单个文件。如果指定,则下载该文件。如果未指定,则下载列表中的第一个文件。根据设备的不同,将显示文件的本机预览。selectedRecordIdselectedRecordIdrecordIds