Using Vue.js to create a Micro Frontend
Anthony Viard 🥑
Posted on June 27, 2022
Disclaimer
This article has been written with the help of the ModSquad Community. The related live session is available here:
Introduction
Hi, fellow developers!
After learning how to create micro frontends with Angular and React, we’re jumping into another world with Vue.js. Remember, we’re trying to create a micro frontend using the web component specifications for each of the following frameworks: Angular, React, and Vue.js.
Does Vue provide the best developer experience when creating a micro frontend social card? Let’s try it!
Create the Vue.js app
First, ensure that you have installed Node with npm (you can use Yarn instead) and Vue CLI.
bash
npm install -g @vue/cli
Then you can create the application by running the following command in your target folder. I suggest using the default option Default ([Vue 3] babel, eslint)
.
bash
vue create vue-social-card
That should create a folder named vue-social-card
that contains a fresh Vue.js project.
Please note that by default the application is configured to include certain features, such as npm scripts to start your app and eslint to help you code.
Discover your application
Before making any changes and creating a micro frontend, let’s run the application locally using the command npm run serve
. Your application should then be available at the following URL: http://localhost:8080/.
Create the social card component
Vue.js helps you organize yourcode with components. That means we need to create a file to contain all the card code. You can delete the default file called HelloWorld.vue
.
Once you’ve created a new file named SocialCard.vue
in the components folder, copy the following code into it:
html
<script>
export default {
props: {
card: {
type: Object,
required: true
}
},
};
</script>
<template>
<div class="card">
<h2>{{ card.name }}</h2>
<span>{{ card.description }}</span>
<img :src="card.image" :alt="card.image_alt"/>
</div>
</template>
<style>
.card {
width: 320px;
height: auto;
min-height: 450px;
background: rgb(60, 62, 68);
border-radius: 20px;
overflow: hidden;
padding: 10px 15px;
margin-bottom: 24px;
margin-right: 10px;
transition: all 0.2s linear;
cursor: pointer;
color: white;
}
img {
margin-top: 5%;
max-width: 100%;
height: auto;
}
.card:hover {
transform: scale(1.01);
box-shadow: 0 3px 12px 0 rgba(0, 0, 0, 0.2),
0 1px 15px 0 rgba(0, 0, 0, 0.19);
}
.card > .title {
margin: 0;
}
</style>
Our component is just a simple piece of HTML/CSS code that requires an entry object named card
and defines the following properties: name
, description
, image
and image_alt
.
As it is, your application might be broken due to an error in the app.vue
file. It’s time to update it.
Update App.vue
The reason your app doesn’t work is that the main component still includes the default component. To fix it, replace the file contents with the following code:
html
<script>
import SocialCard from "@/components/SocialCard";
export default {
components: {
SocialCard
},
data() {
return {
shiba_card: {
id: 1,
name: 'Shiba Inu',
description: 'The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.\n' +
' A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally\n' +
' bred for hunting.',
image: 'https://material.angular.io/assets/img/examples/shiba2.jpg',
image_alt: 'The Shiba Inu image'
},
}
}
};
</script>
<template>
<SocialCard :card=shiba_card></SocialCard>
</template>
This imports our social card component, defines a card object shiba_card
in the data()
function to store the different properties, then passes the card object to the social card component in the template
section.
The application is working again and the default Vue landing page is replaced with the Shiba Inu social card.
However, we only built a classic single page application and need to migrate it to a micro frontend.
Define the custom element
In order to reuse this app as a web component, we need to define a custom element, which is a typical step we discovered when using Angular and React.
Replace the content of the main.js file with the following:
javascript
import App from './App.vue'
import { defineCustomElement } from 'vue'
const SocialCardElement = defineCustomElement(App)
customElements.define('social-card-element', SocialCardElement)
This code defines the social-card-element
custom element and wraps the Vue app. As we saw before, this app is now rendering the card as expected.
Next, replace <div id="app"></div>
in the public/index.html
file with the custom element:
html
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<social-card-element></social-card-element>
<!-- built files will be auto injected -->
</body>
Congratulations! You have just built a Vue.js micro frontend using a custom element.
Please note, as I’m writing this article there is an issue with styling and custom elements that is discussed in detail here: https://github.com/vuejs/core/issues/4662. Please follow this ticket to know when it will be fixed or for current workarounds.
Resources
The code above is available on GitHub: https://github.com/avdev4j/vue-social-card
Thanks to this repo for the card example: https://github.com/AlanPenaRuiz/vue-rick-and-morty
Are you already using Entando and looking for Vue.js components? Take a look at this sample: https://github.com/entando-samples/ent-project-template-vue
Watch micro frontend videos on our YouTube channel: https://www.youtube.com/c/EntandoVideos
Join us on Discord to share and learn about composable apps: https://discord.gg/SdMCvyzzHm
Posted on June 27, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.