{{name}}

Welcome! Let's learn a bit about Vue.js with this interactive demo, shall we? 🤓

Here's a quick preview: try editing the title in the text input field.

data: { name: '{{name}}'}

✨ That magic is all Vue! Let's learn how to set it up.

📩 Including Vue

One of the great things about Vue is how easy it is to get started! There are only two steps, really:

  1. Add a script tag to load the vue.js file:
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.22/vue.min.js"></script>
    (If you're using Vue here on CodePen, you can just add it as an External Script in the JS cog menu.)
  2. Add a bit of JavaScript to create a new Vue instance and set up its options. The most important option is el; this will load our Vue instance into an element on the page (using a CSS/jQuery style selector), and swap out that element's contents with our Vue instance's template:
    const app = new Vue({ el: '#app' //We'll add more options here shortly });

The above code replaces the element that has the ID of app with our new Vue instance. This makes it easy to inject as much or as little Vue functionality as you want into any page or app!

However, our Vue instance doesn't do anything just yet. For that, we'll need an HTML template for Vue to render, and we'll probably want some dynamic data to use in that HTML…

📈 Vue data

Vue stores its data inside the data property of the Vue instance. The data object can hold any type of values (strings, numbers, booleans, arrays, etc.):

const app = new Vue({
    el: '#app', 
    
data { name: '{{name}}', demoData: '{{demoData}}', clickCount: {{clickCount}}, favoriteSites: ['CodePen', 'GitHub', 'Codecademy', 'VueJS'] }
});

This lets you build pages dynamically, so that if the value changes, your HTML will update to reflect the change. You can reference any property inside of data easily with "handlebar" syntax, just by using the property name:

<p>Here's some Vue data: { {demoData} } </p>

Here's some Vue data: {{demoData}}

If you're working here on CodePen, you can enter your template code directly into the HTML pane. Nifty! That's what I've done here, but otherwise, you'll need to put your HTML template code into a template property in the Vue object.

Binding Data to Attributes

Here's the cool part: Vue lets you easily create two-way data binding between form elements and Vue data, so that when either is updated, they automatically stay in sync!

This is done with the v-model directive (which is attached to an HTML attribute—in this case, value ).

Here's how that looks. Edit the input below and watch the above examples change, too!

<input v-model:value="demoData" />
<p>The input says: { {demoData} }</p>
const app = new Vue({
    el: '#app', 
    data {
        name: '{{name}}',
        
demoData: '{{demoData}}',
clickCount: {{clickCount}}, favoriteSites: ['CodePen', 'GitHub', 'Codecademy', 'VueJS'] } });



The input says: {{demoData}}

🖱️ Vue events

Vue allows you to easily watch for and react to events like clicks, user input, form changes and more (without the need to mess with typical JavaScript event listeners). This is done with the v-on attribute, which is attached to the event you'd like to watch for (in this case, "click").

<button v-on:click="updateClickCount">
The button has been clicked { {clickCount} } times. </button>

There are many types of events your Vue instance can "listen" for: click, change, input, keydown and many more. But they're not super useful without…

⚙️ Vue methods

As you might have realized, v-on lets us track events, but we'll still need to create a function to run whenever those events happen.

Vue lets you define any number of methods in (what else?) the methods property. Any methods there can simply be called by name.

So at this point, our code might look like this (with the new methods property highlighted, and added to our button with v-on:click ):

<button v-on:click="updateClickCount">
This button has been clicked { {clickCount} } times. </button>
const app = new Vue({
    el: '#app',
    data {
        name: '{{name}}',
        demoData: '{{demoData}}',
        
clickCount: {{clickCount}},
favoriteSites: ['CodePen', 'GitHub', 'Codecademy', 'VueJS'] },
methods: { updateClickCount: function(){ this.clickCount += 1; } }
});

You might notice that the keyword this refers to the Vue instance. In our templates, calling a data property with handlebar syntax ({{property}}) works perfectly. But when running JS from within the Vue instance, we'll need to specify the scope, with this.property.

🔁 Vue Loops

Oftentimes, we'll have arrays of data in our Vue instance that we need to loop over to display in our HTML. Vue makes this a breeze with the v-for directive!

<ul>
    
<li v-for="site in favoriteSites">{ {site} }</li>
</ul>

Voilà! Multiple <li> tags with a simple line of Vue code!

Iterable Properties

As you might have guessed, if you have an array of objects, v-for allows you to use each object property separately by using it with dot notation:

favoriteSitesDetails: [ {name: 'CodePen', url: 'https://codepen.io'}, {name: 'GitHub', url: 'https://github.com'}, {name: 'Codecademy', url: 'https://www.codecademy.com'}, {name: 'VueJS', url: 'https://vuejs.org'} ]
<ul>
    
<li v-for="site in favoriteSitesDetails"> <a href="site.url">{ {site.name} }</a> </li>
</ul>

We've got a little bit of an issue here, though. Let's find out why!

💥 Dynamic Attributes

If you tried clicking any of those links above, you noticed a problem: all of the links go to site.url.

That's not a real URL, and it's not what we meant when we wrote the href value. We want the attribute's value to be dynamic, not what we literally typed. But we can't use handlebar syntax for HTML attributes, so what can we do?

Easy! Just use the v-bind attribute to indicate that the attribute's value is dynamic Vue data, and not the literal typed value.

<ul>
    <li v-for="site in favoriteSitesDetails">
    
<a v-bind:href="site.url">{ {site.name} }</a>
</li> </ul>

Note that v-bind is very much like v-model, but unlike v-model, v-bind is one-way data binding (not two-way). This means that changing the JS will update the HTML, but not the other way around. This makes v-bind a good choice for non-interactive elements.

(You could add an event and a method to make v-bind two-way, but at that point, it's probably better to just use v-model instead wherever possible.)

📝 Shorthand syntax

As you can imagine, you could often end up using lots of v-on and v-bind directives in your Vue templates. To make the code a little cleaner in these cases, Vue offers shorthand for both.

Here's an example using both shorthands, and using v-bind (or, :) to conditionally add attributes to elements based on a data boolean.

<p :hidden="!isAlert" class="alert">🚨ALERT!</p>
<button @click="toggleAlert">Toggle alert</button>
data: {
    
isAlert: {{isAlert}},
}, methods: {
toggleAlert: function(){ this.isAlert = !this.isAlert; }
}

🚨ALERT!

⁉️ Conditional Attributes

The real power of binding attributes comes with conditional statements. Let's check out how you can dynamically add classes to elements with a ternary expression!

<p:class="isAlert ? 'alert' : 'default'">My class is: { {isAlert ? 'alert' : 'default'} }</p>
<button@click="toggleAlert">Click to toggle class</button>
data: {
    isAlert: {{isAlert}}
},
methods: {
    toggleAlert: function(){
        this.isAlert = !this.isAlert;
    }
}

My class is: {{isAlert ? 'alert' : 'default'}}

Having logic in our HTML templates makes things pretty messy though. There must be a better way, right?

There sure is! Let's look at…

🤖 Computed Properties

As we just saw, having a ternary operator in the middle of our HTML—while it worked well—made things a little tough to read. Good news: that's what computed properties are for!

A computed property is just a function that returns a "computed" value; something that needs to be obtained through an expression. (For example, adding two numbers together, concatenating strings, or in our case: examining a boolean and returning a certain string based on its value.)

So if we want to add the "alert" class to an element when isAlert is true, and a "default" class when isAlert is false (as above), we can tuck that logic away in a computed function (named getClass, in this case) to keep our template file tidy.

<p:class="getClass">My class is: { {getClass} }</p>
<button@click="toggleAlert">Click to toggle class</button>
data: {
    isAlert: {{isAlert}}
},
methods: {
    toggleAlert: function(){
        this.isAlert = !this.isAlert;
    }
},
computed: { getClass: function(){ return this.isAlert ? 'alert' : 'default'; } }

My class is: {{getClass}}

Note that nothing has changed here functionally. This still works exactly as it did before. But now, we have a simple, reusable way to figure out if the "alert" or "default" class should be used, which renders our template file (pun intended) much more readable.

So what's the difference between a computed property and a plain ol' method? Well, in a nutshell:

• Methods can be called at will, can be supplied arguments, and can do anything (including update data values).
• Computed properties aren't called; they're just used in templates. They don't take arguments, and only return a value. In other words (appropriately), they just compute; they don't change things. (Vue also caches them, so they're more performant.)

🎱 Conditional Rendering

We're getting close to the end! One last thing I want to cover: rendering elements conditionally.

The v-if directive allows us to use logic in our templates. For example, let's say we want to show the user one element if loading is true, then swap it out for another once loading is false:

<p v-if="loading">⏳ Loading...</p>
<p v-else>✅ Loaded!</p>

<button @click="toggleLoading">Toggle Loading</button>
data: {
    loading: {{loading}}
},
methods: {
    toggleLoading: function(){
        this.loading = !this.loading;
    }
}

⏳ Loading... ✅ Loaded!

As you might expect, Vue also offers a v-else-if directive, so that you can string together complex conditions based on data!

                <strong>My rating: </strong>
                <span v-if="rating == 1">☹️Bad.</span>
                <span v-else-if="rating == 2">😐Not good.</span>
                <span v-else-if="rating == 3">🙂Ok</span>
                <span v-else-if="rating == 4">😄Good</span>
                <span v-else>😍Great!</span>
                <input type="range" min=1 max=5 v-model:value="rating">
            
data: {
    rating: {{rating}}
}

My rating: ☹️Bad. 😐Not good. 🙂Ok 😄Good 😍Great!

Note: elements using v-if, v-else-if and v-else must be sequential sibling elements in order to work together properly. Any element between them will break the chain.

🤯 There's so much more!

This guide hopefully offers a great way to get started with Vue, but there's a world of possibilities we haven't even discussed yet (including using Vue to create components)!

If you'd like to continue learning Vue, here are a few resources I found helpful:



I hope this guide has been fun and helpful. Thanks for reading! 👋😄


Made by Varun