添加導航和路由

了解如何使用SPA Editor SDK對應至AEM頁面,以支援SPA中的多個檢視。 動態導航是使用React Router和React Core Components實現的。

目標

  1. 了解使用SPA編輯器時可用的SPA模型路由選項。
  2. 了解如何使用React Router在SPA的不同視圖之間導航。
  3. 使用AEM React核心元件來實作由AEM頁面階層驅動的動態導覽。

您將建置的

本章將新增導覽至AEM中的SPA。 導覽功能表將由AEM頁面階層驅動,且會使用導覽核心元件提供的JSON模型。

新增導覽

必備條件

查看設定本地開發環境所需的工具和說明。 本章是映射元件章節的繼續,但是,您只需要部署至本機AEM例項的SPA啟用AEM專案,便能順利完成。

將導覽新增至範本

  1. 開啟瀏覽器並登入AEM, http://localhost:4502/。 應已部署起始代碼庫。

  2. 導覽至​SPA頁面範本:http://localhost:4502/editor.html/conf/wknd-spa-react/settings/wcm/templates/spa-page-template/structure.html

  3. 選擇最外層​根佈局容器,然後按一下其​策略​表徵圖。 請留意​​以選取​版面容器​未鎖定以供編寫。

    選擇根佈局容器策略表徵圖

  4. 建立名為​SPA Structure​的新策略:

    SPA結構原則

    在「允許的元件」>「一般」下,選擇「佈局容器」元件。

    在​允許的元件 > WKND SPA REACT - STRUCTURE​下,選擇​導航​元件:

    選擇導航元件

    在「允許的元件 > WKND SPA REACT — 內容」下,選擇​Image​和​Text​元件。 您應選取總計4個元件。

    按一下​Done​以儲存變更。

  5. 重新整理頁面,並在取消鎖定的​配置容器​上方新增​Navigation​元件:

    將導航元件添加到模板

  6. 選擇​導航​元件,然後按一下其​策略​表徵圖以編輯策略。

  7. 使用​SPA導航​的​策略標題​建立新策略。

    在​Properties​下:

    • 將​導航根​設定為/content/wknd-spa-react/us/en
    • 將​排除根級別​設定為​1
    • 取消選中​收集所有子頁
    • 將​導航結構深度​設定為​3

    配置導航策略

    這將收集/content/wknd-spa-react/us/en下方深處的導覽2層。

  8. 儲存變更後,範本中應該會顯示已填入的Navigation:

    填入的導覽元件

建立子頁面

接下來,在AEM中建立其他頁面,作為SPA中的不同檢視。 我們也會檢查AEM提供的JSON模型的階層結構。

  1. 導覽至​Sites​主控台:http://localhost:4502/sites.html/content/wknd-spa-react/us/en/home。 選擇​WKND SPA React首頁,然後按一下​Create > Page:

    建立新頁面

  2. 在​Template​下,選擇​SPA Page。 在​Properties​下,以​Title​和​page-1​為名稱輸入​Page 1

    輸入初始頁面屬性

    按一下​建立,然後在對話方塊快顯視窗中,按一下​開啟​以在AEM SPA編輯器中開啟頁面。

  3. 將新的​Text​元件添加到主​佈局容器​中。 編輯元件並輸入文本:使用RTE和 H2 元素的第1​頁。

    範例內容頁面1

    您可以隨意新增其他內容,例如影像。

  4. 返回AEM Sites主控台,並重複上述步驟,建立名為​Page 2​的第二個頁面,作為​Page 1​的同層級。

  5. 最後,建立第三個頁面,第3​頁,但作為​第2​頁的​。 完成網站階層後,應如下所示:

    網站階層範例

  6. 導覽元件現在可用來導覽至SPA的不同區域。

    導航和路由

  7. 在AEM編輯器外部開啟頁面:http://localhost:4502/content/wknd-spa-react/us/en/home.html。 使用​導覽​元件來導覽至應用程式的不同檢視。

  8. 在您導覽時,使用瀏覽器的開發人員工具來檢查網路請求。 以下螢幕擷取畫面是從Google Chrome瀏覽器擷取。

    觀察網路請求

    請注意,在初始頁面載入後,後續導覽不會導致完整頁面重新整理,且當返回至先前造訪的頁面時,網路流量會最小化。

階層頁面JSON模型

接下來,檢查可帶來SPA多檢視體驗的JSON模型。

  1. 在新索引標籤中,開啟AEM提供的JSON模型API:http://localhost:4502/content/wknd-spa-react/us/en.model.json。 使用瀏覽器擴充功能將格式化為JSON可能會很有幫助。

    首次載入SPA時,會要求此JSON內容。 外部結構如下所示:

    {
    "language": "en",
    "title": "en",
    "templateName": "spa-app-template",
    "designPath": "/libs/settings/wcm/designs/default",
    "cssClassNames": "spa page basicpage",
    ":type": "wknd-spa-react/components/spa",
    ":items": {},
    ":itemsOrder": [],
    ":hierarchyType": "page",
    ":path": "/content/wknd-spa-react/us/en",
    ":children": {
       "/content/wknd-spa-react/us/en/home": {},
       "/content/wknd-spa-react/us/en/home/page-1": {},
       "/content/wknd-spa-react/us/en/home/page-2": {},
       "/content/wknd-spa-react/us/en/home/page-2/page-3": {}
       }
    }
    

    :children下,應該會看到每個已建立頁面的項目。 所有頁面的內容都位於此初始JSON要求中。 使用導覽路由,後續的SPA檢視將會快速載入,因為內容已在用戶端提供。

    在初始JSON要求中載入SPA內容的​ALL​並不明智,因為這會減緩初始頁面載入速度。 接下來,我們將查看頁面階層深度的收集方式。

  2. 導覽至​SPA根​範本:http://localhost:4502/editor.html/conf/wknd-spa-react/settings/wcm/templates/spa-app-template/structure.html

    按一下​頁面屬性功能表 > 頁面原則:

    開啟SPA根的頁面原則

  3. SPA根​範本有額外的​階層結構​標籤,可控制收集的JSON內容。 「結構深度」​決定了網站階層中的深度,以收集​​下方的子頁面。 您也可以使用​結構模式​欄位,根據規則運算式篩除其他頁面。

    將​結構深度​更新為​2:

    更新結構深度

    按一下​Done​以保存對策略的更改。

  4. 重新開啟JSON模型http://localhost:4502/content/wknd-spa-react/us/en.model.json

    {
    "language": "en",
    "title": "en",
    "templateName": "spa-app-template",
    "designPath": "/libs/settings/wcm/designs/default",
    "cssClassNames": "spa page basicpage",
    ":type": "wknd-spa-react/components/spa",
    ":items": {},
    ":itemsOrder": [],
    ":hierarchyType": "page",
    ":path": "/content/wknd-spa-react/us/en",
    ":children": {
       "/content/wknd-spa-react/us/en/home": {},
       "/content/wknd-spa-react/us/en/home/page-1": {},
       "/content/wknd-spa-react/us/en/home/page-2": {}
       }
    }
    

    注意​Page 3​路徑已移除:/content/wknd-spa-react/us/en/home/page-2/page-3。 這是因為​頁面3​位於階層中的第3層,我們更新了原則,僅包含最大深度為第2層的內容。

  5. 重新開啟SPA首頁:http://localhost:4502/content/wknd-spa-react/us/en/home.html並開啟瀏覽器的開發人員工具。

    重新整理頁面,您應該會看到/content/wknd-spa-react/us/en.model.json(即SPA根)的XHR請求。 請注意,根據先前在教學課程中對SPA根範本進行的階層深度設定,僅包含三個子頁面。 這不包括​第3​頁。

    初始JSON要求 — SPA根

  6. 開啟開發人員工具後,使用Navigation元件直接導覽至​第3​頁:

    請注意,系統已對下列項目提出新的XHR請求:/content/wknd-spa-react/us/en/home/page-2/page-3.model.json

    第3頁XHR請求

    AEM Model Manager了解JSON內容不可用,並自動觸發其他XHR要求。

  7. 直接導覽至:http://localhost:4502/content/wknd-spa-react/us/en/home/page-2.html。 另請注意,瀏覽器的返回按鈕可繼續運作。

Inspect React Routing

導航和路由採用React Router實現。 React Router是React應用程式的導航元件集合。 AEM React核心 元件使用React Router的功能來實 ​施前述步驟中使用的Navigation元件。

接下來,檢查React Router與SPA的整合情況,並使用React Router的Link元件進行實驗。

  1. 在IDE中,在ui.frontend/src/index.js處開啟檔案index.js

    /* index.js */
    import { Router } from 'react-router-dom';
    ...
    ...
     ModelManager.initialize().then(pageModel => {
        const history = createBrowserHistory();
        render(
        <Router history={history}>
            <App
            history={history}
            cqChildren={pageModel[Constants.CHILDREN_PROP]}
            cqItems={pageModel[Constants.ITEMS_PROP]}
            cqItemsOrder={pageModel[Constants.ITEMS_ORDER_PROP]}
            cqPath={pageModel[Constants.PATH_PROP]}
            locationPathname={window.location.pathname}
            />
        </Router>,
        document.getElementById('spa-root')
        );
    });
    

    注意App被包在React RouterRouter元件中。 ModelManager由AEM SPA Editor JS SDK提供,會根據JSON模型API將動態路由新增至AEM頁面。

  2. ui.frontend/src/components/Page/Page.js開啟檔案Page.js

    class AppPage extends Page {
      get containerProps() {
        let attrs = super.containerProps;
        attrs.className =
          (attrs.className || '') + ' page ' + (this.props.cssClassNames || '');
        return attrs;
      }
    }
    
    export default MapTo('wknd-spa-react/components/page')(
      withComponentMappingContext(withRoute(AppPage))
    );
    

    Page SPA元件使用MapTo函式將AEM中的​Pages​對應至對應的SPA元件。 withRoute公用程式可協助根據cqPath屬性以動態方式將SPA路由至適當的AEM子頁面。

  3. ui.frontend/src/components/Header/Header.js開啟Header.js元件。

  4. 更新Header以將Link中的<h1>標籤包裝到首頁:

      //Header.js
      import React, {Component} from 'react';
    + import {Link} from 'react-router-dom';
      require('./Header.css');
    
    export default class Header extends Component {
    
        render() {
            return (
                <header className="Header">
                <div className="Header-container">
    +              <Link to="/content/wknd-spa-react/us/en/home.html">
                        <h1>WKND</h1>
    +              </Link>
                </div>
                </header>
            );
        }
    

    我們不使用React Router提供的預設<a>錨點標籤,而是使用<Link>。 只要to=指向有效的路由,SPA就會切換到該路由,而​not​會執行完整的頁面刷新。 在此,我們只需將首頁的連結硬式編碼,以說明Link的使用方式。

  5. ui.frontend/src/App.test.js更新測試。App.test.js

    + import { BrowserRouter as Router } from 'react-router-dom';
      import App from './App';
    
      it('renders without crashing', () => {
        const div = document.createElement('div');
    -   ReactDOM.render(<App />, div);
    +   ReactDOM.render(<Router><App /></Router>, div);
      });
    

    由於我們在App.js中引用的靜態元件內使用React Router的功能,因此需要更新單元測試以考慮該功能。

  6. 開啟終端機,導覽至專案的根目錄,並使用您的Maven技能將專案部署至AEM:

    $ cd aem-guides-wknd-spa.react
    $ mvn clean install -PautoInstallSinglePackage
    
  7. 導覽至AEM中SPA的其中一個頁面:http://localhost:4502/content/wknd-spa-react/us/en/home/page-1.html

    請使用Header中的連結,而非使用Navigation元件進行導覽。

    標題連結

    請注意,已觸發完整頁面重新整理為​not,且SPA路由正在運作。

  8. 或者,使用標準<a>錨點標籤來實驗Header.js檔案:

    <a href="/content/wknd-spa-react/us/en/home.html">
        <h1>WKND</h1>
    </a>
    

    這有助於說明SPA路由與一般網頁連結之間的差異。

恭喜!

恭喜您,您已了解如何使用SPA Editor SDK對應至AEM頁面,以支援SPA中的多個檢視。 動態導航已使用React Router實現,並添加到Header元件中。

本頁內容