Web组件
[AEM Headless as a Cloud Service]{class="badge informative"}
示例应用程序是探索Adobe Experience Manager (AEM)的Headless功能的好方法。 此Web组件应用程序演示了如何使用AEM的GraphQL API通过持久查询来查询内容,以及如何呈现部分UI(使用纯JavaScript代码完成)。
具有AEM Headless的 
          
          
在GitHub🔗上查看源代码
先决条件 prerequisites
应在本地安装以下工具:
AEM要求
Web组件可与以下AEM部署选项配合使用。
- AEM as a Cloud Service
 - 使用AEM Cloud Service SDK进行本地设置
                  
- 需要JDK 11(如果连接到本地AEM 6.5或AEM SDK)
 
 
此示例应用依赖于要安装basic-tutorial-solution.content.zip,并且所需的部署配置已准备就绪。
person.js文件中提供了身份验证,则它可以从AEM Author获取内容。使用方法
- 
                  
克隆
adobe/aem-guides-wknd-graphql存储库:code language-shell $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git - 
                  
导航到
web-component子目录。code language-shell $ cd aem-guides-wknd-graphql/web-component - 
                  
编辑
.../src/person.js文件以包含AEM连接详细信息:在
aemHeadlessService对象中,更新aemHost以指向您的AEM发布服务。code language-plain # AEM Server namespace aemHost=https://publish-p123-e456.adobeaemcloud.com # AEM GraphQL API and Persisted Query Details graphqlAPIEndpoint=graphql/execute.json projectName=my-project persistedQueryName=person-by-name queryParamName=name如果连接到AEM Author服务,请在
aemCredentials对象中,提供本地AEM用户凭据。code language-plain # For Basic auth, use AEM ['user','pass'] pair (for example, when connecting to local AEM Author instance) username=admin password=admin - 
                  
打开终端并运行来自
aem-guides-wknd-graphql/web-component的命令:code language-shell $ npm install $ npm start - 
                  
新的浏览器窗口将打开一个静态HTML页面,该页面嵌入了http://localhost:8080处的Web组件。
 - 
                  
人员信息 Web组件显示在网页上。
 
代码
以下摘要介绍了Web组件的构建方式、它如何连接到AEM Headless以使用GraphQL持久查询检索内容,以及这些数据的呈现方式。 完整的代码可在GitHub上找到。
Web组件HTML标记
可重复使用的Web组件(又称自定义元素)<person-info>已添加到../src/assets/aem-headless.html HTML页面。 它支持host和query-param-value属性来驱动组件的行为。 host属性的值覆盖person.js中aemHeadlessService对象的aemHost值,并且query-param-value用于选择要呈现的人员。
    <person-info
        host="https://publish-p123-e456.adobeaemcloud.com"
        query-param-value="John Doe">
    </person-info>
            Web组件实施
person.js定义了Web组件功能,下面是其中的关键亮点。
PersonInfo元素实施
<person-info>自定义元素的类对象通过使用connectedCallback()生命周期方法、附加影子根、获取GraphQL持久查询和DOM操作来创建自定义元素的内部影子DOM结构来定义功能。
// Create a Class for our Custom Element (person-info)
class PersonInfo extends HTMLElement {
    constructor() {
        ...
        // Create a shadow root
        const shadowRoot = this.attachShadow({ mode: "open" });
        ...
    }
    ...
    // lifecycle callback :: When custom element is appended to document
    connectedCallback() {
        ...
        // Fetch GraphQL persisted query
        this.fetchPersonByNamePersistedQuery(headlessAPIURL, queryParamValue).then(
            ({ data, err }) => {
                if (err) {
                    console.log("Error while fetching data");
                } else if (data?.personList?.items.length === 1) {
                    // DOM manipulation
                    this.renderPersonInfoViaTemplate(data.personList.items[0], host);
                } else {
                    console.log(`Cannot find person with name: ${queryParamValue}`);
                }
            }
        );
    }
    ...
    //Fetch API makes HTTP GET to AEM GraphQL persisted query
    async fetchPersonByNamePersistedQuery(headlessAPIURL, queryParamValue) {
        ...
        const response = await fetch(
            `${headlessAPIURL}/${aemHeadlessService.persistedQueryName}${encodedParam}`,
            fetchOptions
        );
        ...
    }
    // DOM manipulation to create the custom element's internal shadow DOM structure
    renderPersonInfoViaTemplate(person, host){
        ...
        const personTemplateElement = document.getElementById('person-template');
        const templateContent = personTemplateElement.content;
        const personImgElement = templateContent.querySelector('.person_image');
        personImgElement.setAttribute('src',
            host + (person.profilePicture._dynamicUrl || person.profilePicture._path));
        personImgElement.setAttribute('alt', person.fullName);
        ...
        this.shadowRoot.appendChild(templateContent.cloneNode(true));
    }
}
            注册<person-info>元素
            // Define the person-info element
    customElements.define("person-info", PersonInfo);
            跨源资源共享(CORS)
此Web组件依赖于在目标AEM环境中运行的基于AEM的CORS配置,并假定主机页面在开发模式下运行于http://localhost:8080,以下是本地AEM Author服务的CORS OSGi配置示例。
请查看各个AEM服务的部署配置。