V-IF ~ Condition

Now we will learn about v-if directive. This is a conditional directive. Let's see how it is used -

		<div v-if="hasName">
			{{ vname }}
		</div>
		data :{
			name : "Santanu Bera",
			hasName : false
		}
	

If you run the code, you will see nothing. But if you change the value of hasName to true, you will see the output as Santanu Bera. The directive v-if accepts boolean value, and it is attached to an element. If the value is true then the element will be rendered, and if the value is false, the element will not be rendered. It's like rendering the element based on a condition. The coolest part is if you change the value of hasName to true dynamically, the element will be rendered dynamically too.

You can also use inline expression or computed property that returns true.

		<div v-if="age == 30">
			{{ vname }}
		</div>
		data :{
			name : "Santanu Bera",
			age : 30
		}
	
		<div v-if="hasName">
			{{ vname }}
		</div>
		data :{
			name : "Santanu Bera",
			age : 30
		},
		computed:{
			hasName:function(){
				if(this.name != ""){ return true; }else{ return false;}
			}
		}
	

! Operator

We all know what this operator is. It's called Not operator. It returns true if the value is false and it returns false if the value is true.

If hasName is true, then !hasName is false.. I hope you get it.

Now we can use this operator inside the v-if directive.

		<div v-if="!hasName">
			Amazing
		</div>
		data :{
			name : "Santanu Bera",
			age : 30
		},
		computed:{
			hasName:function(){
				if(this.name != ""){ return true; }else{ return false;}
			}
		}
	

Now, you will see Amazing if hasName is false.

V-ELSE

We, all know why we use else block for. The general mechanism exist in every language. If the v-if directive evaluates to false, the v-else will be rendered. And v-else block will be skipped if the v-if evaluates to true.

One thing to remember that, the v-else must immediately follow v-if directive. Otherwise the element won't be rendered properly and you will get an error in the console.

You are not limited to use v-if and/or v-else in div element, you can use on any HTML element you want.

		<div v-if="hasName">
			{{ vname }}
		</div>
		<div v-else>
			No Name
		</div>
		data :{
			name : "Santanu Bera",
			age : 30
		},
		computed:{
			hasName:function(){
				if(this.name != ""){ return true; }else{ return false;}
			}
		}
	

V-ELSE-IF

Just like every other programming language Vue also provides else if block. You already know how it goes.

		<div v-if="age>30">
			You are a Man
		</div>
		<div v-else-if="age<30">
			You are a Boy
		</div>
		<div v-else>
			You are In.
		</div>
		data :{
			age : 30
		}
	

You can have more than one v-else-if directive. One thing to remember that, every v-else-if directive must immediately follow the previous v-else-if directive and first v-else-if must follow v-if directive. And if there's v-else directive it must immediately follow v-if directive or last v-else-if directive if ther's any.

v-if on <template>

As v-if is a directive, it must be used with a single element. But what if you want to use it for more than one element? One solution that might come up in your mind is that, we can use v-if directive on each element. Well it's kind of lot of work if there's are lot of elements. Like this -

		<div v-if="hasName">
			Do Something
		</div>
		<div v-if="hasName">
			Do Something Else
		</div>
		<div v-if="hasName">
			Do Anything
		</div>
		.
		.
		.
	

Another solution is, which is very convenient, use a wrapper div with the v-if directive.

		<div v-if="hasName">
			<div>
				Do Something
			</div>
			<div>
				Do Something Else
			</div>
			<div>
				Do Anything
			</div>
			.
			.
			.
		</div>
	

Well, it's good, but you will need to have another unwanted div element for that. To solve the problem Vue provides us a built in component element <template> which we can use in this case.

		<template v-if="hasName">
			<div>
				Do Something
			</div>
			<div>
				Do Something Else
			</div>
			<div>
				Do Anything
			</div>
			.
			.
			.
		</template>
	

Now, this time if you look at the DOM, the element <template> is removed from the final rendered result. It servs as invisible wrapper. Pretty Cool.

key

Consider the following example -

		<div v-if="isActive" style="margin-bottom: 10px;">
			<label>User Name</label>
			<input type="text" name="username" placeholder="User Name" class="input is-info">
		</div>
		<div v-else style="margin-bottom: 10px;">
			<label>Email</label>
			<input type="text" name="email" placeholder="Email" class="input is-success">
		</div>
		<div style="display: flex; justify-content: flex-end;">
			<button class="button is-success" v-on:click="toggle" class="input is-success">Toggle</button>
		</div>
		new Vue({
			el : "#Page",
			data : {
				isActive : true
			},
			methods:{
				toggle:function(){
					this.isActive = !this.isActive;
				}
			}
		});
	

And you will get the following output -

Now, write something in the text box and click the botton Toggle, to toggle the element. You will see all has changed but what you have typed is still in the textbox. The value that is typed in the username textfiled is available in the email textfield. How's that Possible? Well, from Vue's documentation "Vue tries to render elements as efficiently as possible, often re-using them instead of rendering from scratch. Beyond helping make Vue very fast, this can have some useful advantages.". Now it is clear, that Vue tries to reuse an element as far as possible instead of render them from the scratch. So before Vue render the email div block, Vue will take the common elements from the username div block. If the attribute, style or value is different for the new element, Vue will just update them instead of rendering from the scratch.

Well, sometimes you don't want that. Sometimes you want Vue to render element from the scratch. So the way to tell Vue is using key attribute with unique value.

		<div v-if="isActive" style="margin-bottom: 10px;">
			<label>User Name</label>
			<input type="text" name="username" placeholder="User Name" class="input is-info" key="username-input">
		</div>
		<div v-else style="margin-bottom: 10px;">
			<label>Email</label>
			<input type="text" name="email" placeholder="Email" class="input is-success" key="email-input">
		</div>
		<div style="display: flex; justify-content: flex-end;">
			<button class="button is-success" v-on:click="toggle" class="input is-success">Toggle</button>
		</div>
		new Vue({
			el : "#Page",
			data : {
				isActive : true
			},
			methods:{
				toggle:function(){
					this.isActive = !this.isActive;
				}
			}
		});
	

And you will get the following output --

Now, if you type in the textbox and click the toggle button, you won't see the previous value because this time Vue rendered email div block from the scratch. It didn't take anything from the username div block.

Note that the <label> elements are still efficiently re-used, because they don’t have key attributes.

v-show

This is another conditional directive provided by Vue. The directive v-if and v-show are almost same. However, there are some differences and they are --

We should use v-show if the conditional block needs to be changed many times. v-if should be used if the conditional block is unlikely to change many times dynamically.

		<div v-show="hasName">
			{{ vname }}
		</div>
		data :{
			name : "Santanu Bera",
			hasName : false
		}