...
Always use a computed property when possible:
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
Inline object:
<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
Array syntax:
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
Inline styles with computed property:
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
or inline object:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
v-if
if the condition is unlikely to change at runtime.v-show
if you need to toggle something very often or for a lot of elements.v-if
and v-for
togetherExample use with if/else:
<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>
Vue tries to render elements as efficiently as posible, so the <input>
won't be replaced, just the placeholder
. If you want to avoid this, add a key
attribute with unique values:
<input placeholder="Enter your username" key="username-input">
To give Vue a hint so that it can track each node’s identity when reusing and reordering existing elements, provide a unique key
attribute for each item wherever possible:
<ul id="example-2">
<li v-for="(item, index) in items" v-bind:key="item.id">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
//...
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo', id: 5 },
{ message: 'Bar', id: 6 }
]
}
You can also use v-for="item of items
, more closer to javascript syntax for iterators.
Array change detection:
push() / pop() / shift() / unshift() / splice() / sort() / reverse()
) mutate the original array they are called on, so will also trigger view updatesfilter() / concat() / slice()
) you can replace the old array with the new one returned: this.items = this.items.filter(...)
this.items[2] = newValue
(not detected by Vue) you can use Vue.set(this.items, 2, newValue)
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }}: {{ value }}
</div>
//...
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
}
*When iterating over an object, the order is based on the key enumeration order of Object.keys()
, which is not guaranteed to be consistent across JavaScript engine implementations.
Object change detection:
data
object) to an already created instancevar vm = new Vue({
data: {
a: 1
}
})
vm.b = 2 //this new property won't be reactive
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
Vue.set(vm.userProfile, 'age', 27)
If you want to assign several new properties to an existing object, you should create a fresh object with properties from both objects:
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
<li v-for="n in evenNumbers">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
<li v-for="n in even(numbers)">{{ n }}</li>
//...
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
v-for
on a custom component (a key is required):<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id"
></my-component>
is
attribute where you need valid HTML to avoid browser parsing error:<ul>
<li
is="todo-item" <!-- same than <todo-item> -->
v-for="(todo, index) in todos"
v-bind:key="todo.id"
v-bind:title="todo.title"
v-on:remove="todos.splice(index, 1)"
></li>
</ul>
v-for
on a <template>
to render a block of multiple elements.<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
v-for
with a Range:<span v-for="n in 10">{{ n }} </span> //will repeat the template that many times.
v-for
has a higher priority than v-if
:<li v-for="todo in todos" v-if="!todo.isComplete"> //v-if will be run on each iteration of the loop separately
{{ todo }}
</li>
(...)