LWC Router 스스로 만들기

16901 단어 SalesforcelwcRouter

1. 목적



이번 스스로 개발한 Salesforce측 사용할 수 있는 LWCRouter를 소개합니다.
현재 React나 Vue 등 각자 자신의 Router가 있어, SPA에서의 화면 천이입니다만,
LWC에는 Router와 같은 라이브러리가 없지만 slot 태그, NavigationMixin 및
CurrentPageReference를 사용하여 Router와 같은 기능을 구현할 수 있습니다.

2. 소스 구성도


lwc
    ├─router
    ├─myRouterContainer
    ├─pageA
    ├─pageB

router





router.html
<template>
    <template if:true={isCurrentPageName}>
        <slot></slot>
    </template>
</template>

router.js
import { LightningElement, api, wire } from 'lwc';
import { CurrentPageReference, NavigationMixin } from 'lightning/navigation';
export default class Router extends NavigationMixin(LightningElement) {
    //ルーターパス宣言
    @api path;

    //現在のルーターパス
    @wire(CurrentPageReference)
    currentPageReference;
    /**
     * 現在のページかを判断する
     */
    get isCurrentPageName() {
        const { c__pageName } = this.currentPageReference.state;
        const { path } = this;
        return path === c__pageName;
    }
}

router.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>

myRouterContainer





myRouterContainer.html
<template>
    <!-- デフォルトページ -->
    <c-router>
        <c-page-a></c-page-a>
    </c-router>
    <!-- ページ -->
    <c-router path="A">
        <c-page-a></c-page-a>
    </c-router>
    <c-router path="B">
        <c-page-b></c-page-b>
    </c-router>
    <!-- ページ追加↑↑↑↑ -->
</template>

myRouterContainer.js
import { LightningElement } from 'lwc';

export default class myRouterContainer extends LightningElement {}

myRouterContainer.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

페이지 A





pageA.html
<template>
    <div class="slds-card" style="height:300px">
        <div>ここはページA</div>
        <lightning-button onclick={navigateToB} label="ページBへ遷移"></lightning-button>
    </div>
</template>

pageA.js
import { LightningElement, wire } from 'lwc';
import { NavigationMixin, CurrentPageReference } from 'lightning/navigation';
export default class PageA extends NavigationMixin(LightningElement) {

    //現在のルーターパス
    @wire(CurrentPageReference)
    currentPageReference;

    /**
     * 画面Bへ遷移
     * @param {*} event 
     */
    navigateToB(event) {
        event.preventDefault();
        this.navigateToNextPage('B');
    }

    /**
     * 画面遷移
     * @param {*} pageName 
     */
    navigateToNextPage(pageName) {
        const { apiName } = this.currentPageReference.attributes;
        this[NavigationMixin.Navigate]({
            type: 'standard__webPage',
            attributes: {
                url: `/lightning/n/${apiName}?c__pageName=${pageName}`
            }
        });
    }
}

pageA.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>

페이지 B





pageB.html
<template>
    <div class="slds-card" style="height:300px">
        <div>ここはページB</div>
        <lightning-button onclick={navigateToA} label="ページAへ遷移"></lightning-button>
    </div>
</template>

pageB.js
import { LightningElement, wire } from 'lwc';
import { NavigationMixin, CurrentPageReference } from 'lightning/navigation';
export default class PageB extends NavigationMixin(LightningElement) {

    //現在のルーターパス
    @wire(CurrentPageReference)
    currentPageReference;

    /**
     * 画面Bへ遷移
     * @param {*} event 
     */
    navigateToA(event) {
        event.preventDefault();
        this.navigateToNextPage('A');
    }

    /**
     * 画面遷移
     * @param {*} pageName 
     */
    navigateToNextPage(pageName) {
        const { apiName } = this.currentPageReference.attributes;
        this[NavigationMixin.Navigate]({
            type: 'standard__webPage',
            attributes: {
                url: `/lightning/n/${apiName}?c__pageName=${pageName}`
            }
        });
    }
}

pageB.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>

3.Salesforce 측 동작 확인



Salesforce 측 Lightning 구성 요소 탭 만들기





탭 열기



기본값은 페이지 A 표시


페이지 B로 전환 버튼을 누르면 페이지 A에서 페이지 B로 전환됩니다.


페이지 A로 전환 버튼을 누르면 페이지 B에서 페이지 A로 전환합니다.

좋은 웹페이지 즐겨찾기