DEV Community

Cover image for A beginner's guide to VueJS
Aman Kumar
Aman Kumar

Posted on

A beginner's guide to VueJS

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>

Enter fullscreen mode Exit fullscreen mode

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",
    };
    },
});
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
// BELOW data METHOD
methods: {
    changeText() {
        this.my_message = "Hello from Vue!";
    },
},
Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

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`);
},
Enter fullscreen mode Exit fullscreen mode

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>`
    ,
});

Enter fullscreen mode Exit fullscreen mode

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"],
Enter fullscreen mode Exit fullscreen mode

Now try adding this custom component in your main html. You can use this anywhere in your code like this:

<custom-heading />
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
// BELOW template
props: ["msg"],
Enter fullscreen mode Exit fullscreen mode

In the parent component, pass msg attribute to <custom-heading />.

<custom-heading msg="Hello From Parent Component" />
Enter fullscreen mode Exit fullscreen mode

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" />
Enter fullscreen mode Exit fullscreen mode

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>")
Enter fullscreen mode Exit fullscreen mode

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");
},
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
thomasbnt profile image
Thomas Bnt

Hello ! Don't hesitate to put colors on your codeblock like this example for have to have a better understanding of your code 😎

console.log('Hello world!');
Enter fullscreen mode Exit fullscreen mode

Example of how to add colors and syntax in codeblocks

Collapse
 
dustyworld666 profile image
Aman Kumar

Thank you for the suggestion. That makes it much better 😃

Collapse
 
rcls profile image
OssiDev

I personally advocate using Composition API over Options API. Using it helps you switch between Vue and React.

Collapse
 
kissu profile image
Konstantin BIFERT

CAPI is more difficult than OAPI overall + Vue is still easy to grasp but this may help some React developers indeed.

Collapse
 
gabrielgomeso profile image
Gabriel Gomes de Oliveira

I've never thought about that. Personally, I like Options better but that is an excellent explanation of why people might prefer Composition API

Collapse
 
aarone4 profile image
Aaron Reese

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)

Collapse
 
kissu profile image
Konstantin BIFERT

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. 👌🏻

Collapse
 
dustyworld666 profile image
Aman Kumar

Yeah, sorry about that, forgot to mention. Thanks for sharing.