添加导航和路由

了解如何通过SPA Editor SDK将SPA中的多个视图映射到AEM页面,从而支持中的多个视图。 动态导航是使用React Router和React Core Components实现的。

目标

  1. 了解使用SPA编辑器时可用的SPA模型路由选项。
  2. 了解如何使用React Router在SPA的不同视图之间导航。
  3. 使用AEM React核心组件实施由AEM页面层次结构驱动的动态导航。

将构建的内容

本章将向AEM中的SPA添加导航。 导航菜单将由AEM页面层次结构驱动,并将利用导航核心组件提供的JSON模型。

添加了导航

前提条件

查看设置本地开发环境所需的工具和说明。 本章是映射组件章节的继续,但是,随后您只需要将一个启用了SPA的AEM项目部署到本地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 — 内容>下,选择​图像​和​文本​组件。 您应选择总共4个组件。

    单击​完成​以保存更改。

  5. 刷新页面,并在未锁定的​布局容器​上方添加​导航​组件:

    将导航组件添加到模板

  6. 选择​导航​组件并单击其​策略​图标以编辑策略。

  7. 使用​SPA Navigation​的​策略标题​创建新策略。

    在​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主页​并单击​创建 > 页面:

    创建新页面

  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:

    更新结构深度

    单击​完成​以保存对策略所做的更改。

  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的XHR请求,该请求是SPA根。 请注意,根据本教程前面对SPA根模板进行的层次结构深度配置,只包含三个子页面。 这不包括​第3​页。

    初始JSON请求 — SPA根

  6. 打开开发人员工具后,使用Navigation组件直接导航到​第3​页:

    请注意,新的XHR请求已发布到:/content/wknd-spa-react/us/en/home/page-2/page-3.model.json

    第3页XHR请求

    AEM模型管理器了解​第3​页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以将<h1>标记包含在Link中,以包装到主页:

      //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提供的<Link>默认的<a>锚点标记。 只要to=指向有效路由,SPA就会切换到该路由,并且​not​会执行全页刷新。 在本例中,我们只需对指向主页的链接进行硬编码,以说明Link的用法。

  5. App.test.jsui.frontend/src/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组件进行导航。

    标题链接

    请注意,完整的页面刷新是​​触发的,并且SPA路由正在工作。

  8. 或者,也可以使用标准<a>锚点标记来试验Header.js文件:

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

    这有助于说明SPA路由与常规网页链接之间的差异。

恭喜!

恭喜,您了解了如何通过SPA Editor SDK将SPA中的多个视图映射到AEM页面来支持这些视图。 动态导航已使用React Router实现并添加到Header组件中。

在此页面上