Vue 2 | Conditional Branching and Computed Properties
To switch whether elements or attributes are shown or hidden depending on conditions, use the v-show and v-if directive attributes.
- Vue 2.5.4
Difference Between v-show and v-if
The difference is that v-show simply hides something from the screen with CSS display: none, while v-if removes its existence at the DOM level.
If you switch between showing and hiding many times, v-show is better for performance. However, even when v-show is not visible, it continues monitoring the internal state.
If there is a lot of internal data, or if an error occurs unless a specific object exists, and you do not want processing to run while it is merely hidden, it is better to use v-if.
Showing Only Data That Meets a Specific Condition in a List
Using the following data, suppose we want to show only products whose price is less than or equal to the entered value.
new Vue({
el: '#app',
data: {
price: 300,
inputprice: 200,
list: [{
name: 'Tomato',
price: 100
}, {
name: 'Lettuce',
price: 200
}, {
name: 'Cucumber',
price: 300
}]
}
})
The syntax is the same for both v-show and v-if.
<li v-for="val in list" v-show="condition">Shown when the condition is satisfied.</li>
In the condition part, write an expression like the one you would put inside the parentheses of a JavaScript if statement. If it is a method name, pass data that represents a Boolean value.
<ul>
<!-- Shows when val.price is smaller than the entered price -->
<li v-for="val in list" v-show="val.price <= price">
{{ val.name }} {{ val.price }} won
</li>
</ul>
<input v-model.number="inputprice" size="5"> Show products at or below this price
<!-- When the button is pressed, price is updated and the result updates at the same time. -->
<button @click="price = inputprice">click!</button>
If you use the inputprice value connected to v-model, it searches in real time. In this example, however, we want to search when the button is pressed, so we assign the input value to a data item named price and use that as the condition.
When you enter a number and click, only products with prices below that value are displayed. In a real application, you need to handle cases where values other than numbers are entered, but here we will only check the simple feature that enables real-time filtering.
By the way, v-model also includes the modifier .number, which converts input values to numbers.
Adding Conditions to Styles and Classes
<ul>
<li v-for="val in list" v-show="!price || val.price <= price">
{{ val.name }} <span v-bind:style="{color: val.price <= 200 ? 'red' : 'blue'}">{{ val.price }}won</span>
</li>
</ul>
In the example above, prices of 200 won or less are shown in red. Because style and class can have multiple values, v-bind can attach conditions to each of them in object form. If there are normally written style and class attributes without v-bind, the merged result is displayed.
<span :style="{ color: colorValue }">Text</span>
<span :class="{ active: price < 200 }">Text</span>
For colorValue, write data containing an expression or Boolean value. You can also pass an object or a processed string value.
<span :style="styleObject">Text</span>
Using Computed Properties
Now suppose we also want to display messages such as “Found X items” or “No items found.” How should we get the number of data items found in the final search? Looking at the official guide, there is something called “computed properties.” This is a feature that can process data during a search, so using it should make this possible.
Computed properties can return the result of some processing as a data value. The difference from the previous example is that by the time the value is passed to v-for, it is already an array containing only items that satisfy the condition. You can append text, remove unnecessary items, create new data from the data you currently have, and do many other things. Like methods, functions are defined in the computed option. Although they are defined as functions, they are used as properties, as the name suggests.
new Vue({
el: '#app',
data: {
price: 300,
inputprice: 200,
list: [{
name: 'Tomato',
price: 100
}, {
name: 'Lettuce',
price: 200
}, {
name: 'Cucumber',
price: 300
}]
},
computed: {
matchList: function() {
console.log('matchList') // This is a test, so leave a log when it runs.
// Use filter to create and return an array containing only items below price.
return this.list.filter(function(val) {
return val.price <= this.price
}, this)
}
}
})
We created a simple computed property named matchList.
<ul>
<li v-for="val in matchList">
{{ val.name }} {{ val.price }} won
</li>
<li v-if="!matchList.length">
No matching products.
</li>
</ul>
<input v-model.number="inputprice" size="5"> Show products at or below this price
<button @click="price = inputprice">click!</button>
Found {{ matchList.length }} items.
If you process the data first in a computed property and then look at the result’s length, you can know how many items were found.
Because matchList is used in three places, I was worried that the function might run each time. After adding console.log, it ran only once. Computed properties seem to be cached until the data they use changes. Nice, isn’t it? That means there is an advantage over using a method.
Computed properties are cached based on their dependencies.
In other words, if dependent data changes, the computed property is synchronized as well. If you do not want the display to update immediately after a change, or if you want to create new data under certain conditions, it is better to use watch, which is covered in another article.
Setting Multiple Conditions with v-if / v-else-if / v-else
You can use the v-else-if and v-else directives together with v-if. Be sure to place them immediately after the conditional element.
<div v-if="conditionA">Condition A</div>
<div v-else-if="conditionB">Condition B</div>
<div v-else>No match.</div>
Conclusion
Conditional branching is essential when building applications. Computed properties are extremely convenient. It is also useful to understand when to use methods depending on the situation. Next, we will finally explain components.