In the previous blog post I have explained a simple (dummy) way of how we can add Vue to an Adobe Experience based project. Now it is time to add a bit more complexity.
package.json
file that will be needed{
"name": "aem-ktln",
"version": "1.0.0",
"description": "",
"main": "script.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"vue": "^2.5.16"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.6.1",
"webpack": "^4.5.0",
"webpack-cli": "^2.0.14"
}
}
We will have only one dependency here and it is "vue": "^2.5.16"
. Additionally, there will be a bunch of devDependencies:
Below is the content of the webpack.config.js
file
const path = require('path');
module.exports = {
mode: 'development',
entry: {
main: ['./src/main/content/jcr_root/etc/designs/aem-ktln/clientlib-site/js/script.js'] // initial script, entry point, starts out app
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, './target/classes/etc/designs/aem-ktln/clientlib-site/js') // destination path
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
]
},
resolve: {
alias: {
'vue': 'vue/dist/vue.js' // to use vue with compiler
}
},
devtool: 'inline-source-map'
};
Quite good at this point, but we need to integrate the Webpack build into our Maven build.
We need to add one more plug-in to run NPM and Webpack commands
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v8.11.1</nodeVersion>
<npmVersion>5.8.0</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
</execution>
<execution>
<id>webpack build</id>
<goals>
<goal>webpack</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
We are done with the app building (boring) part and ready to modify our application code.
We have introduced a js entry point in the Step 1 script.js
Now we are ready to look inside.
import Vue from 'vue'
import components from './components.js' //1
function startApp() {
components.forEach(func => func()); //2
const elements = document.querySelectorAll('[data-component]'); //3
([]).forEach.call(elements, (el) => {
el.dataset.initialized = 'true';
new Vue({el: el}); //4
});
}
document.addEventListener("DOMContentLoaded", startApp); //5
data-component
attribute. That’s how we mark our Vue componentsdata-component
attributeDOMContentLoaded
eventNot rocket science at all :)
import counter from '../../../../../apps/aem-ktln/components/content/counter/clientlib/js/counter.js'
const components = [];
components.push(...[
counter]);
export default components;
import Vue from 'vue';
function counter() {
Vue.component('counter', {
props: ['number', 'buttonText'],
template: `<div>
<button @click="increment">{{buttonText}}</button>
<h3>{{counter}}</h3>
</div>`,
methods: {
increment() {
this.counter++;
}
},
data() {
return {
counter: Number.parseInt(this.number)
}
}
})
}
export default counter
That’s it! The last thing we have to do is simply deploy and check live.
It is working but it’s not a production-ready solution. Instead you should think about it as a starting point.
Lots of things can be improved: * How to register components * How to define templates * inline * x-template * string * State management if required * etc
If you have any thoughts and ideas about it do not hesitate to share them in the comments below, e-mail me or report it as an issue at github