一. 跳转服务

跳转在项目中用到的随处可见,跳转到某一条记录,跳转到某个app,跳转到home页面,跳转到一个自定义component等等,lwc里通过Navigation Service实现跳转工作,即lwc组件头部引入lightning/navigation。

需要注意的是,navigation service只支持 Lightning Experience, Experience Builder sites, 以及mobile app,其他场景不支持,比如在vf中使用lightning component。

Navigation Service核心内容是PageReference。它是一个描述页面类型、其属性和页面状态的JavaScript对象。使用PageReference使你的组件不受未来URL格式变化的影响。它还允许你的组件在多个应用程序中使用,每个应用程序可以使用不同的URL格式。

我们以一个例子进行更好的展开,下面的demo为跳转到不同类型的页面。

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
      );
    }
}

通过上面代码,我们可以看到以下内容:

上述只是基于demo进行的整理,哪里可以看到PageReference的所有的类型以及相关属性设置呢?请参考文章最后的文档。

二. 通知展示

lwc针对通知类型的展示可以整理成五类:alert / confirm / Prompt / Toast / Customize Modal. 其中 alert / confirm / prompt针对window的这三个方法,因为Chrome和Safari不支持跨域iframe的调用,所以官方封装了针对这三个方法的lightning下跨域无障碍功能组件。

  1. Alert Modal:使用此通知类型,可以展示一个阻止用户,并传达一个影响他们的系统、功能或页面的紧急错误。使用方法为引入LightningAlert然后调用LightningAlert.open()方法即可。

    此方法返回一个promise,如果想要弹出内容点击OK以后想要调用相关逻辑,可以在promise的then中进行处理。

    import { LightningElement } from 'lwc';
    import LightningAlert from 'lightning/alert';
    
    export default class MyApp extends LightningElement {
    
        showSpinner = false;
    
        // async handleAlertClick() {
        //     await LightningAlert.open({
        //         message: 'this is the alert message',
        //         theme: 'error', // a red theme intended for error states
        //         label: 'Error!', // this is the header text
        //     });
        //     //Alert has been closed
        // }
    
        handleAlertClick() {
            /*
            theme available options
              default: white
            shade: gray
            inverse: dark blue
            alt-inverse: darker blue
            success: green
            info: gray-ish blue
            warning: yellow
            error: red
            offline: black
            */
            this.showSpinner = true;
            LightningAlert.open({
                message: 'this is the alert message',
                theme: 'error', // a red theme intended for error states
                label: 'Error!', // this is the header text
                variant: "header"
            }).then((result) => {
                //当点击OK按钮以后的调用内容
                console.log('execute')
                this.showSpinner = false;
            });
        }
    }
    

    上述demo中只描述了JS部分,点击button,会弹出一个警告框效果,颜色可以基于注释内容修改,promise的then不是必须的,如果不需要点击OK后续效果,可以参考上方注释内容。

    Untitled

  2. Confirm Modal:使用此通知类型,展示一个modal,让用户选择继续还是取消操作。使用此方法引入LightningConfirm然后调用LightningConfirm.open()方法即可。和上述alert的demo差不多,我们直接看一下confirm的demo

    confirmSample.html

    <template>
        <lightning-button onclick={handleConfirmClick} label="Open Confirm Modal">
        </lightning-button>
    </template>
    

    confirmSample.js

    import { LightningElement } from 'lwc';
    import LightningConfirm from 'lightning/confirm';
    
    export default class ConfirmSample extends LightningElement {
        async handleConfirmClick() {
            const result = await LightningConfirm.open({
                message: 'this is the prompt message',
                label: 'this is the aria-label value'
            });
            //如果点击 OK按钮,result返回true,如果点击cancel按钮,返回false
            if(result) {
            	console.log('execute OK button');
            } else {
            	console.log('execute cancel button');
            }
        }
    }
    
  3. Prompt Modal:使用此通知类型,展示一个modal,有一个输入框,让用户选择继续还是取消操作。使用此方法引入LightningPrompt然后调用LightningPrompt.open()方法即可。和上述confirm的demo差不多,我们直接看一下prompt的demo。

    promptSample.html

    <template>
        <lightning-button onclick={handlePromptClick} label="Open Prompt Modal">
        </lightning-button>
    </template>
    

    promptSample.js

    import { LightningElement } from 'lwc';
    import LightningPrompt from 'lightning/prompt';
    
    export default class PromptSample extends LightningElement {
        handlePromptClick() {
            LightningPrompt.open({
                message: 'this is the prompt message',
                //theme defaults to "default"
                label: 'Please Respond', // this is the header text
            }).then((result) => {
                if(result) {
                	console.log('输入的内容为: ' + result);
                } else {
                	console.log('click cancel');
                }
            });
        }
    }
    

    效果可看下图

    Untitled

  4. Toast Modal:弹出一个modal,用来提醒用户成功,失败或者警告。toast可以设置不同的模式,比如3秒后小时,点击X才消失以及组合内容。我们可以想到的toast就是当数据创建成功以后,系统会弹出一个绿色的提示条,然后几秒以后消失,这个就是toast的实现。toast可以实现简单的文字提示,也可以带链接的样式。想要实现Toast,可以分成两步。

    1. js端引入toast→import { ShowToastEvent } from 'lightning/platformShowToastEvent';
    2. 构造 ShowToastEvent的事件,并且调度事件
    const evt = new ShowToastEvent({
        title: this._title,
        message: this.message,
        variant: this.variant,
    });
    this.dispatchEvent(evt);
    

    我们以一个例子更好的了解。

    toastSample.html

    <template>
    	<lightning-button-group>
    		<lightning-button label="普通Toast" onclick={showToast}></lightning-button>
    		<lightning-button label="带URL Toast" onclick={showURLToast}></lightning-button>
    	</lightning-button-group>
    </template>
    

    toastSample.js:这里着重说一下基于链接的toast,message/title 通过花括号方式设置预置内容,然后通过messageData注入即可。

    import { LightningElement, track, wire } from 'lwc';
    import { ShowToastEvent } from 'lightning/platformShowToastEvent';
    export default class toastSample extends LightningElement {
    	showToast() {
    		const evt = new ShowToastEvent({
    		    // title: '测试title',
    		    message: '测试消息内容',
    		    variant: 'info',
    		});
    		this.dispatchEvent(evt);
    	}
    
    	showURLToast() {
    		const event = new ShowToastEvent({
                title: 'Success!',
                message: 'Record {0} created! See it {1}!',
    						variant: 'success',
                messageData: [
                    'Salesforce',
                    {
                        url: '<http://www.salesforce.com/>',
                        label: 'here',
                    },
                ],
            });
            this.dispatchEvent(event);
    	}
    }
    

    效果展示:

    Untitled