Vue Components are an amazing way to expand html with reusable code. By using components you can use custom html that makes the code much more legible. I have created a few component examples in my VueJS repository (mainly based on Jeffrey Way’s work at Laracasts).
Component Advantages
So why are Vue Components so cool? Why should you use them? What makes the use of them better for us frontend developers?
- They are global and can be reused as many times as you want. Meaning you can call them in html as many times as you need to call them.
- Great way to organize your frontend code in a nested tree structure. With let’s say headers, navbars, footers that can be loaded inside page, post or product components with other components like modals
- Allow you to have template, JavaScript and styling in one .vue file
- Extends you Vue instance*
- Better to have data per app element in its own area then having all in one Vue instance. Otherwise things would get unruly real quick
* Data should be a function so it is not shared across Vue component instances
See https://youtu.be/nyJSd6V2DRI
Message Component
The Vue component project in the repo I will be using is the component that creates a basic message. It shows a basic message with the option to hide it with a click. This component uses a .js file and html file that loads the data. We do not use a Vue file here yet.
Vue Components defined
As said Vue Components are new Vue instances that can use the same options as a new Vue instance. They allow you to use:
- clean reusable code
- expand html
- custom html tags
Vue Component Initiation
A Vue component always must be registered before the Vue instance itself. So we could as we do in this example start with
Vue.component('message', { props: ['title', 'body'], data() { return { isVisible: true }; },
- title
- body
These are referenced later in the template. Using these properties you can override message title and message body in the actual html. This way you can also use one component with multiple html tags to manipulate. No need to create two in this case.
Vue Data
The data option object here returns boolean true for isVisible.This is the function attached to the v-show directive in the Vue template.
NB Most of the options that can be passed into the Vue constructor can be used in a component, with one special case: data must be a function
Vue Template
The Vue object option is where you add all the html that will be used to replace / expand upon in the actual index.html or other html document. It is the view in the Vue’s MVVM stack. It is also where you call the component properties you defined earlier:
template: ` <article class="message" v-show="isVisible"> <div class="message-header"> {{title}} <!-- @click is a short version of v-on:click and you can add a method to be called --> <button class="delete" @click="hideModal" aria-label="delete"></button> </div> <div class="message-body"> {{body}} </div> </article> `,
There is a lot of things going on here. The template data is put between backticks. There we add the actual message html. We use the v-show directive to show or hide the message based upon a function called later in the data option.
The button added has a v-on directive to trigger an event using the hideModal method called upon later.
You also see title and body called using moustache brackets. That way the message as loaded in the html will be loaded there when the html for message is replaced.
Vue Methods
The method we use here is hideModal. As mentioned it will be triggered when the button is called using v-on. And that will make the function isVisible attached to v-show false and thereby hiding the message box:
methods: { hideModal() { this.isVisible = false; } } });
Vue Initiation
So as stated we finally call Vue itself using:
new Vue({ el: '#root' })
HTML
The actual html manipulated by the component is very short and sweet:
<!DOCTYPE html> <html> <head> <title></title> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.5.1/css/bulma.css"> <style type="text/css" media="screen"> body {padding-top:40px;} </style> </head> <body> <div id="root" class="container"> <message title="Hello World" body="Lorem ipsum dolor sit amet, consectetur adipiscing elit. "></message> </div> <script src="https://unpkg.com/vue"></script> <script src="./js/main.js" type="text/javascript" charset="utf-8" async defer></script> </body> </html>
It loads Vue from a CDN, Bulma CSS and our Vue component using main.js. As you can see Vue is called before the component of course. What you should also see is that root is added as id to mark the area where Vue will work and that message title and body are added. The latter two are newly created html tags as we mentioned can be done with Vue. Making the html all the clearer to read.