Hey DEV.to community!
Since I love Vue.js and enjoy writing it I'll be covering almost every basic concept of Vue.js (based on the official website) in this post and put a table of content so you can access the section you want with more ease.
This part won't cover components.
Some code samples are also from the official website. Visit Vue.js
There is a Japanese version of this article available at https://qiita.com/_masa_u/items/7a940f1aea8be4eef4fe Thanks to
Table of content
- Interpolations
- Binding
- Two-way data binding
- Events
- Dynamic arguments
- Computed properties
- Watchers
- Conditional render
- List rendering
Interpolations
Interpolation means putting or rendering your data which is possible very easily using Vue's double-mustache syntax.
Simple interpolation
By using double-mustache syntax you can render your data:
<span>My name is: {{ myName }}</span>
Interpolation with expression
Interpolations can contain simple expressions in Vue.
Simple expression interpolation
You can also use JavaScript expressions inside double-mustaches:
<span>I'm {{ myAge + 5 }} years old!</span>
You can also use methods to manipulate your data and return an string or integer to be rendered:
<span>My pets' names are {{ myPets.join(", ") }}</span>
Ternary operator expression interpolation
You can also use ternary operator to have a simple conditional rendering:
<span>I'm a {{ myAge > 50 ? 'kinda old' : 'young' }}!</span>
Note:
- You can only use one expression inside double-mustaches
- An expression is different than a statement. For example the code below won't work because it is not and expression, but a statement: ```vue
{{ let msg = 'Hello World!'; }}
- Flow control is not supported in double-mustaches:
```vue
<!--THIS IS WRONG-->
{{ if(true) { return 'Yes!' } }}
Raw HTML interpolation
If you don't want to escape your data and render it as real HTML use the v-html
directive:
<span v-html="myHTMLData"></span>
Warning: Rendering HTML can be risky since it can cause into XSS attacks on your website.
Binding
Binding means using your data inside your tag's attributes.
Simple binding
Something wrong that new Vue developers try to do is putting a data into a attribute like this:
<span class="{{ myClass }}"></span>
But this is wrong and you actually have to bind it:
<span v-bind:class="myClass"></span>
There is a shorter way of binding which is by omitting v-bind
directive, like below:
<span :class="myClass"></span>
Binding with concat
So what if you want to combine some string with your data when binding? Well use put your string inside of quotes and concat it as usual:
<span :class="myClass + 'test'"></span>
This can really be useful by using it inside hyperlinks:
<a :href="baseURL + '/post/' + postId">Read more</a>
The example above is a good example of a link to the post including the base URL and the post
suffix and then the post id.
Conditional binding
You can use bindings to conditionally do something.
For the attributes which don't have a value like disabled
or required
if your bound data return true the attribute will be added and if returns false the attribute won't be added to the element.
<button :disabled="true"></button>
You can also use expressions which return boolean:
<button :disabled="password.length < 6"></button>
You can use an object inside the class attribute in order to bind the specified class if the condition is met:
<div :class="{green: true, red: false}"></div>
In the example above green
class will be added to our div
but not red.
You can use comparison and logical operators as well:
<div :class="{green: 5 > 1, red: false && 9 < 16}"></div>
Two-way data binding
By using the v-model
directive you can create a two-way data binding. Which means the user can change the data using an input and see the result simultaneously if needed.
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
let app = new Vue({
el: '#app',
data: {
message: ''
}
});
The v-model
directive can work on almost every input type.
Events
Events are called when a specific action is performed on an element.
Events are declared with v-on
directive.
<div id="app">
<button v-on:click="callMyfunction"></button>
</div>
let app = new Vue({
el: '#app',
methods: {
callMyfunction() {
alert('This is it!');
}
}
});
When a click is performed on this button it will call the callMyFunction
method.
You can use anonymous functions as well:
<button v-on:click="() => alert('Hello my friend')"></button>
There is shorthand for events as well:
<button @click="() => alert('Hello my friend')"></button>
Dynamic arguments
Imagine when you want to have an attributes name evaluated. Well this is possible by doing like below:
<div v-bind:[myAttribute]="myData"></div>
You can also have an event's name dynamically attached:
<div v-on:[myEvent]="doSomething"></div>
Dynamic arguments by object
There is also a way of binding dynamic arguments by using an object and JavaScript's native dynamic key syntax, like below:
<button v-on="{[myAttr]: true}">Click on me if you can</button>
let app = new Vue({
el: '#app',
data: {
myAttr: 'disabled'
}
});
This can be used on events as well:
<button v-on="{[myEvent]: function() { alert("Hello world!") }}">Hi</button>
let app = new Vue({
el: '#app',
data: {
myEvent: 'click'
}
});
Computed properties
Computed properties are a way of cleaning your code and use them instead of expressions inside of your double-mustaches or other places.
Imagine you have the code below:
<p>
The best programming languages are: {{ programmingLanguages }}<br>
But the worst are: {{ programmingLanguages.split(', ').reverse().join(', ') }}
</p>
Instead you can define a computed property like below and use it instead of worst programming languages:
<p>
The best programming languages are: {{ programmingLanguages }}<br>
But the worst are: {{ worstProgrammingLanguages }}
</p>
let app = new Vue({
el: '#app',
data: {
programmingLangauges: 'JavaScript, C#, PHP, Python, LALALA, HOHOHO'
}
computed: {
worstProgrammingLanguages() {
return this.programmingLangauges.split(', ').reverse().join(', ');
}
}
});
The order is not real and I'm not judging any programming language. It is just for demonstration.
Computed properties are getters which means they only return something and have no role in setting the data.
You can change this behaviour and set both set
and get
methods for a data, like below:
let app = new Vue({
el: '#app',
data: {
myFirstName: 'Adnan',
myLastName: 'Babakan'
}
computed: {
myFullName: {
get(): {
return this.myFirstName + ' ' + this.myLastName;
},
set(v): {
let parts = v.split(' ');
this.myFirstName = parts[0];
this.myLastName = parts[1];
}
}
}
});
The code above will split the string by space and set the first part as first name and the second part as the last name when you are trying to set a data to myFullName
but when getting the data it will concat first name and last name.
Watchers
A more generic way of knowing when a data changes is by using watchers.
let app = new Vue({
el: '#app',
data: {
myAge: 19
}
watch: {
myAge(v) {
console.log('I\'m now ' + v);
}
}
});
Note: Watchers don't manipulate data unless you want.
Conditional rendering
A conditional rendering is used when you want to display parts of your UI according to some condition(s).
<span v-if="isUserLoggedIn">Hello user</span>
<span v-else>Hi guest!</span>
Your conditions can have an 'else-if' as well:
<span v-if="favoriteColor === 'red'">Red like apple</span>
<span v-if="favoriteColor === 'blue'>Blue like sky</span>
<span v-else>Hmmm....</span>
Vue is smart and will only replace the parts that are different.
For example if you have a an input for logging in by email or username switching between two parts by condition won't erase and re-render that input and user's inputted value won't be deleted:
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
Though, by using key
you can tell Vue that these fields are completely different and you should re-render them:
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
Toggle display conditional rendering
By using v-show
you render the element but hide it (setting the display
property to none
) like this:
<span v-show="true">Hello there!</span>
Note: v-show
doesnβt support the <template>
element, nor does it work with v-else
.
Note: v-if
is lazy which means the block with false condition at the beginning won't be rendered, on the other hand v-show
actually renders but hides the block.
List rendering
Rendering a list of data is almost like looping in other programming languages.
Array rendering
Often it happens you want to iterate around an array and render them.
This is possible by using v-for
directive:
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
});
You can also pass a second argument to access the index of current item:
<ul id="example-2">
<li v-for="(item, index) in items">
{{ index }} - {{ item.message }}
</li>
</ul>
var example2 = new Vue({
el: '#example-2',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
});
Object rendering
Object rendering is no harder than array rendering:
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
});
You can also have access to the name of the property using the second argument:
<ul id="v-for-object" class="demo">
<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
});
Accessing to the index is also available when iterating around an object:
<ul id="v-for-object" class="demo">
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
});
Iterate in range
Iterating in a range of numbers is also pretty easy:
<div>
<span v-for="n in 10">{{ n }} </span>
</div>
Check out my free Node.js Essentials E-book here:
Top comments (10)
Hi Adnan and thanks for your article! I didn't knew we could bind dynamic property with this syntax, reminds me the way Angular does it. I though there were only the
v-bind="{attribute: value}"
syntax which you didn't mention if I'm being correct (also working forv-on="{event: handler}"
).Also, I didn't knew we could iterate over numbers! This
v-for="n in 10"
looks very handy.Hi
Thanks for your comment
I will add what you said to the list.
Thanks
Hello Adnan,
Really great article! Well done. You mentioned quite a few things I had forgotten about in Vue.js.
Keep up the great work.
Do you accept smaller development jobs, by the way?
Martin
Hi Martin
Thanks for your comments.
Yes I would love to.
That's great!
To be fair to you, I should ask you first if there is a way I could pay you.
I'm not quite sure how that would work as I am in Bangkok, and you're in Tabriz.
And if you prefer to talk about this on another communication channel like WhatsApp or any other, just let me know.
Bravoπ
Waiting for cheat sheet 2, 3, 4, ... β€
Cheat sheet 2 coming right away!
This is really great! Learning Vue 3 at the moment. Did a little video on ways I've been learning it - would have included this cheat sheet, if I'd known about it before!
youtu.be/OPiMJ787-c0
I am really happy that you found it useful. I'd be glad to add your video to the post if you make one. Just let me know. :)