Intro
Hey there, everybody. In this article, I'll be showing you how you can start your journey with VueJS, a popular front-end framework. This guide will help you understand the basics of VueJS to a level where you'll be able to carry on with it and build some awesome projects.
What is VueJS?
If you go to their official website, it is written that:
Vue (pronounced /vjuː/, like view) is a JavaScript framework for building user interfaces. It builds on top of standard HTML, CSS, and JavaScript, and provides a declarative and component-based programming model that helps you efficiently develop user interfaces, be it simple or complex.
A few things we understand from it are:
- It's a front-end framework like React or Angular.
- It provides a declarative and component-based programming model. Here declarative means an element pulls down information only from state and props. Component-based means code can be divided into components and reused instead of writing the same logic again and again.
VueJS uses two API styles, Options, and Composition API. In options API, we define a component's logic using an object of options such as data, methods and mounted. In composition API, we use imported API functions like ref
and onMounted
.
For this article, I'll be using the options API only. Feel free to explore the docs for the composition API.
So without further ado, let's get started.
Setup
Surprisingly enough, all you need for this tutorial is a simple HTML file! Simply create an HTML file and add the below code to it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<h1>Hello From Vue</h1>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({});
app.mount("#app");
</script>
</body>
</html>
It's pretty straightforward. All we're doing is adding a VueJS CDN and mounting it on div with id "app". It means that we can write vuejs-like syntax which we'll discuss in the next part.
Declarative Rendering
As described earlier, VueJS is built on top of simple javascript, HTML, and CSS, which allows us to declaratively describe the HTML output through the javascript state. Let's create our state and try to render it on HTML. Refactor the const app = Vue.createApp({})
line so that it looks like this:
const app = Vue.createApp({
data: () => {
return {
my_message: "Hello World",
};
},
});
Here we're defining data
, which is a special method that returns an object with states. For this example, we've defined a state variable my_message
inside the data
. Now inside the app
div, create a <h1>
tag and add {{my_message}}
to it. Try running the file on the browser, you be getting Hello World as the output.
Reactivity
Now, let's say I have a button and on clicking it I want to change my_message
to Hello from Vue!. For this, we'll create a method to change the text. In VueJS, we define methods in the methods: {} object. Create a methods
object below the data method and define a changeText method. Also, add a button inside HTML just like mentioned below:
<!-- ANYWHERE INSIDE div with id app -->
<button v-on:click="changeText">Change Text</button>
// BELOW data METHOD
methods: {
changeText() {
this.my_message = "Hello from Vue!";
},
},
Now try opening your browser and click on the button. The output should change to Hello from Vue!. Now those coming from React might feel a bit weird because in react we're used to defining both state and a function responsible for changing the current state. In Vue, we're directly changing our state. This is possible because of reactivity which means that Vue automatically tracks JavaScript state changes and efficiently updates the DOM when changes happen. This, along with the declarative rendering, constitutes the key features of VueJS.
Directives
In the previous example, we've defined a v-on:click
attribute on the button. This is known as a directive. They're special attributes with the prefix v-
. VueJS provides a number of built-in directives. Some of the most commonly used ones are:
- v-on: Attaches an event listener. One can also use
@<event-name>
as a shorthand syntax. - v-if/v-else-if/v-else: Applies conditional rendering.
- v-show: Same as v-if, however instead of add or removing the element altogether, it just hides the element (display: hidden).
- v-for="elem in arr"/key="": Iterates over the provided array and renders elements as many times as the length of the array. It requires the key attribute to be used, to uniquely identify the elements.
- v-bind:: Dynamically binds the attribute to a state. Shorthand property
:<attribute>
You can check out other directives in the docs.
Let's try to use some of the directives mentioned above. Suppose we want to render a list of items. Try adding an array with a list of items in it, in the state. Now, use v-for
attribute to render it on the dom, just like mentioned below.
<ul>
<li v-for="(item, idx) in items" :key="idx">
Item number {{idx + 1}} - {{item}}
</li>
</ul>
In order to provide a dynamic key, you can bind it using v-bind:key
or :key
for short. Try adding v-if and v-show as well.
Lifecycle Methods
Each vue component goes through a series of phases, mounting, updating, and un-mounting. Vue provides some special methods, a.k.a Lifecycle methods, that you can use whenever necessary. The most common use case includes fetching data from the server, logging, etc. Some commonly used methods are:
- created: Called after the instance has finished processing all state-related options.
- mounted: Called after the component is rendered on the dom.
- updated: Called after there are some changes in the dom.
- unmounted: Called after the component is removed from the dom.
created() {
console.log(`App is created`);
},
updated() {
console.log(`App is mounted`);
},
Initially, you'll see App is created
inside the console. Now click the Change Text
button we created earlier. You should see App is mounted
in the console this time.
Custom Components
In the beginning, I told you that VueJS provides component-based programming model. That means we can create our custom components. Let's try creating one. Add this to your code right before the app.mount("#app")
line:
app.component("custom-heading", {
template:
`<h1>Hello From Custom Component</h1>`
,
});
Here we're creating a custom-heading
component, and inside it, we're just defining a simple h1 tag. Also, in order to use the custom components, you need to register them inside the components
array. Add the below code right below the updated
method:
components: ["custom-heading"],
Now try adding this custom component in your main html. You can use this anywhere in your code like this:
<custom-heading />
So far so good. One thing we're missing here is how can we pass data to the child components. Let's try implementing that. Suppose we want to render our own custom message in the child component. For this, we need to accept the props in the child components. Add the props array below the template
and instead of a hard-coded message inside the h1 tag, use the variable inside the props.
<!-- INSIDE TEMPLATE -->
<h1>{{msg}}</h1>
// BELOW template
props: ["msg"],
In the parent component, pass msg attribute to <custom-heading />
.
<custom-heading msg="Hello From Parent Component" />
You can also give it dynamically using the v-bind:<attribute>
directive.
You can also emit events from the child component to the parent component. In the parent component, you can listen for events using v-on
directive mentioned below.
<custom-component v-on:response="(text) => my_message = text" />
What this will do is, it will keep on listening for a response
event. When that happens, it will set the my_message variable to whatever we get from the child component. This is one of the main advantages of using VueJS overreact. In react, if you need to get anything from the child component, you first need to uplift the state and then pass on the callback function to the child component. This allows getting data from child components in a much simpler fashion.
Now in order to emit a response add the response in the emits array and emit the response event like this:
this.$emit("response", "<your message>")
You can use it anywhere, be it a button event or inside lifecycle hooks. I've used it inside the created
method like this:
created() {
this.$emit("response", "Howdy");
},
This should change our my_message
variable to Howdy.
Conclusion
I hope I've covered enough to get you started with your next major project. Feel free to write your thoughts about the article in the comments section.
Thank you for reading. I hope you enjoyed it :).
Top comments (8)
Hello ! Don't hesitate to put colors on your
codeblock
like this example for have to have a better understanding of your code 😎Thank you for the suggestion. That makes it much better 😃
I personally advocate using Composition API over Options API. Using it helps you switch between Vue and React.
CAPI is more difficult than OAPI overall + Vue is still easy to grasp but this may help some React developers indeed.
I've never thought about that. Personally, I like Options better but that is an excellent explanation of why people might prefer Composition API
I started with Vue 2 as the spiritual successor to the original Angular.js and the simplicity of Options was part of the appeal. Vue Options Vs React classes was an easy choice for me. Vue Composition Vs React functions is much less clear.
I get why they introduced Composition for larger code bases keeping functionality together by concept rather than operations makes it easier to manage but I find the syntax verbose and cluttered with ref(var) and var.value everywhere in the js.
I think there are more footguns in Composition and for me at least it was harder to learn and distracted from the simplicity of Vue.
That said, I think I would still pick composition+pinia (Vue 3) over options+vuex4(Vue 2)
Hey, thanks for the article!
Be careful of not using
:key="idx"
, it's actually counter-productive. You need a real unique identifier like some data UUID for example. 👌🏻Yeah, sorry about that, forgot to mention. Thanks for sharing.