在AEM中向Vue组件传递页面数据的技术咨询
解答你的AEM + Vue动态导航问题
问题1:为什么直接输出${sidebarNavigationModel.items}显示逗号,传给Vue变成字符串?
这其实是Sightly模板引擎和Java集合的默认行为导致的:
- 当你在Sightly中直接输出Java集合(比如你的
ArrayList<Page>)时,Sightly会自动调用集合的toString()方法。而Java的ArrayList.toString()逻辑是遍历所有元素,调用每个元素的toString(),然后用逗号把这些结果拼接起来。 - 你看到一堆逗号,是因为
Page对象的toString()方法没有输出有意义的文本(或者输出的内容被页面过滤器过滤掉了),所以最终就只剩分隔用的逗号了。 - 当你把这个拼接出来的字符串传给Vue组件时,Vue的
itemsprops如果定义的是数组类型,自然会报错——因为你传递的是一个纯字符串,不是它期望的数组结构。
问题2:如何获取站点子页面数据并整理为可传递给Vue组件的数据集?
要让Vue能正确接收数组格式的导航数据,你需要把Java中的Page列表转换成JSON格式的字符串,再传递给Vue组件(Vue会自动把JSON字符串解析成JavaScript数组)。具体步骤如下:
步骤1:修改Java模型,将Page数据转为结构化对象并序列化为JSON
首先在你的SidebarNavigationModel里,把Page对象的关键属性(比如路径、标题、子页面)提取成简单的POJO,再用JSON工具把它序列化为字符串:
package services.agro.something.core.models; import java.util.*; import java.util.Iterator; import com.day.cq.wcm.api.Page; import com.day.cq.wcm.api.PageFilter; import com.adobe.cq.sightly.WCMUsePojo; import com.fasterxml.jackson.databind.ObjectMapper; public class SidebarNavigationModel extends WCMUsePojo{ // 新增:存储JSON格式的导航数据 private String itemsJson; private Page rootPage; // 自定义导航项POJO,只保留Vue需要的属性 public static class NavItem { private String path; private String title; private List<NavItem> children; public NavItem(Page page, PageFilter filter) { this.path = page.getPath() + ".html"; this.title = page.getTitle() != null ? page.getTitle() : page.getName(); this.children = new ArrayList<>(); // 递归获取子页面(如果需要下拉菜单的话) Iterator<Page> childPages = page.listChildren(filter); while (childPages.hasNext()) { this.children.add(new NavItem(childPages.next(), filter)); } } // 自动生成getter(Jackson需要getter来序列化) public String getPath() { return path; } public String getTitle() { return title; } public List<NavItem> getChildren() { return children; } } @Override public void activate() throws Exception { rootPage = getCurrentPage().getAbsoluteParent(2); if (rootPage == null) { rootPage = getCurrentPage(); } PageFilter filter = new PageFilter(getRequest()); Iterator<Page> childPages = rootPage.listChildren(filter); // 把Page列表转为NavItem列表 List<NavItem> navItems = new ArrayList<>(); while (childPages.hasNext()) { navItems.add(new NavItem(childPages.next(), filter)); } // 序列化为JSON字符串 ObjectMapper mapper = new ObjectMapper(); this.itemsJson = mapper.writeValueAsString(navItems); } // 新增:返回JSON格式的导航数据 public String getItemsJson() { return itemsJson; } public Page getRoot() { return rootPage; } }
步骤2:在Sightly模板中传递JSON数据给Vue组件
修改模板代码,用Vue的绑定语法(:items)传递JSON字符串,同时确保Sightly不转义JSON中的引号:
<div data-sly-use.sidebarNavigationModel="services.agro.gde.core.models.SidebarNavigationModel" class="sidebar-navigation ae-spacing-indent"> <div class="sidebar-nav-container"> <!-- 使用Vue的v-bind语法(简写:items),并指定context='unsafe'避免转义引号 --> <sidebar-navigation title="${properties.title}" :items="${sidebarNavigationModel.itemsJson @ context='unsafe'}" ></sidebar-navigation> </div> <!-- 原有测试代码可以保留或删除 --> <ul class="nav navbar-nav navbar-center"> <li><a href="${sidebarNavigationModel.root.path}.html">HOME</a></li> <li class="nav navbar-nav navbar-left" data-sly-repeat="${sidebarNavigationModel.items}"> <a href="${item.path}.html">${item.title}</a> </li> </ul> </div>
关键注意点:
- 用
:items而不是items:这是Vue的v-bind语法,告诉Vue要把属性值当成JavaScript表达式解析,而不是纯字符串。 @ context='unsafe':让Sightly不转义JSON中的双引号,否则Vue拿到的会是转义后的字符串(比如"path": "/content/..."),无法正确解析成数组。- 递归子页面:如果你的导航需要下拉菜单,上面的代码已经处理了子页面的递归转换,如果不需要,可以去掉
children相关的逻辑。
内容的提问来源于stack exchange,提问作者wuno
相关产品推荐
相关产品推荐

