A beginner's guide to VueJS
Tags: vue, javascript, beginners, tutorial
Published: 2022-09-16 08:36:56

##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](https://vuejs.org/) 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](https://vuejs.org/api/composition-api-setup.html#composition-api-setup) 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.

```html
<!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:

```js
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:

```html
<!-- ANYWHERE INSIDE div with id app -->
<button v-on:click="changeText">Change Text</button>
```

```js
// 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:<attribute>: Dynamically binds the attribute to a state. Shorthand property `:<attribute>`

You can check out other directives in the [docs](https://vuejs.org/api/built-in-directives.html#built-in-directives).

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.

```html
<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.

```js
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:
```js
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:

```js
components: ["custom-heading"],
``` 
Now try adding this custom component in your main html. You can use this anywhere in your code like this: 
```html
<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.
```html
<!-- INSIDE TEMPLATE -->
<h1>{{msg}}</h1>
```

```js
// BELOW template
props: ["msg"],
```
In the parent component, pass msg attribute to `<custom-heading />`. 

```html
<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.

```html
<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:

```js
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:

```js
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 :).