Complete guide for integrating Vue.js 2.7 components with AEM 6.5 Touch UI.
Tích hợp Vue 2 vào AEM 6.5 Maven Archetype
Ghi chú thực chiến: Tích hợp Vue 2.7.x vào
ui.frontendcủa AEM Maven archetype 39+, bao gồm đăng ký component, truyền props từ HTL, và mount nhiều Vue instance trên một trang.
Tổng quan kiến trúc
Luồng dữ liệu:
Bước 1: Tạo AEM Maven Project
Dùng AEM Archetype 39 (phiên bản ổn định nhất với AEM 6.5).
frontendModule
Chọn general để dùng Webpack thuần. Không chọn react hay angular vì sẽ kéo theo dependency thừa.
Bước 2: Cài đặt Vue 2 vào ui.frontend
vue và vue-template-compiler phải cùng minor version. Ví dụ cả hai đều 2.7.16.
Bước 3: Cấu hình Webpack
Mở ui.frontend/webpack.common.js (hoặc webpack.config.js tùy archetype version), thêm VueLoaderPlugin:
vue$ alias
vue/dist/vue.esm.js là full build (bao gồm cả compiler). Cần thiết nếu bạn dùng template: '...' dạng string trong component. Nếu chỉ dùng .vue files (SFC) thì có thể dùng vue/dist/vue.runtime.esm.js nhẹ hơn.
Bước 4: Tạo Vue Component (SFC)
Bước 5: Đăng ký Component & Mount trong main.js
Đây là phần cốt lõi của integration. Trong AEM, mỗi component HTL render ra một DOM element riêng — không phải SPA, không có root duy nhất. Ta cần tìm tất cả mount points và khởi tạo Vue instance cho từng cái.
Khuyến nghị cho AEM: Dùng Auto-import nếu project có nhiều component và dùng Webpack (archetype mặc định). Dùng Thủ công nếu cần kiểm soát rõ component nào được load.
require.context chỉ chạy trên Webpack
Nếu project dùng Vite (hiếm trong AEM 6.5), thay bằng import.meta.glob:
new Vue(\{ el: '#app' \}) duy nhất?
AEM render nhiều component độc lập trên cùng một trang. Mỗi component HTL có DOM element riêng. Cần mount nhiều Vue instance — mỗi instance trên một element.
Bước 6: Tạo AEM Component
6.1 Cấu trúc thư mục
6.2 Component definition — .content.xml
6.3 HTL Template — mount point
HTL mặc định escape HTML. Với string thường thì không sao. Nhưng với JSON array/object, cần dùng @ context='unsafe' hoặc pass qua Sling Model dưới dạng string đã được serialize sẵn.
6.4 Author Dialog — _cq_dialog/.content.xml
Bước 7: Sling Model (Java)
Sling Model đọc properties từ JCR và expose ra HTL. Với array/object cần serialize sang JSON.
@ValueMapValue vs @ChildResource
@ValueMapValue— lấy single value (String, int, boolean, String[])@ChildResource— lấy child node (dùng cho multifield phức tạp) :::
Bước 8: ClientLib — tích hợp Webpack output vào AEM
Webpack build ra file JS vào ui.apps/src/main/content/jcr_root/apps/myvuesite/clientlibs/clientlib-site/js/. AEM cần ClientLib để include file này.
8.1 Cấu trúc ClientLib
8.2 ClientLib definition
8.3 Include ClientLib trong Page template HTL
Bước 9: Webpack config — output đúng đường dẫn
Đảm bảo Webpack output thẳng vào thư mục ClientLib.
::: tip Archetype đã cấu hình sẵn
Archetype 39 đã có script sync để copy build output vào đúng chỗ. Kiểm tra package.json trong ui.frontend xem có script build:clientlib hay không.
Bước 10: Build & Deploy
Pattern nâng cao: Multiple Vue instances với event bus
Khi nhiều component Vue cần giao tiếp trên cùng một trang mà không cần Vuex:
Checklist tích hợp
Gotchas thường gặp
1. Vue component không mount
2. Props boolean nhận sai giá trị
HTL $\{model.showButton\} render ra string "true" hoặc "false". JSON.parse sẽ convert đúng:
3. JSON array bị HTL escape
HTL escape <, >, " mặc định. Array JSON chứa " sẽ bị break.
4. vue-template-compiler version mismatch
5. AEM Author mode vs Publish mode
Trong Author mode, AEM có thể render thêm wrapper div cho WCM. Cần kiểm tra selector [data-vue-component] vẫn hoạt động: