In regular HTML there's no way to change the attribute value of an HTML element dynamically. You need Javascript or JQuery to change the value of the attribute. And thanks to Vue.js which makes it even simpler. For Example take an look at this example -------
<div id="Example"> <input type="text" v-bind:placeholder="name"> </div> <script type="text/javascript"> new Vue({ el : "#Example", data : { name : "Type your name"; } }); </script>
Now if you run the above script you will get the followin --
If you can see, the value of the property "name" is automatically reflected in the HTML attribute. This way we can change any HTML tag's attribute.
The v-bind directive also works on boolean property. Before going further let's take a look at the following example -
<div id="Example"> <button v-bind:disabled="isActive"></button> </div> <script type="text/javascript"> new Vue({ el : "#Example", data : { isActive : true } }); </script>
If you change isActive : false
, the button will be activated. Well, the way it works little bit different from the earlier example. When the value isActive
is false
, the boolean attribute attribute
is removed from the DOM and when the value of isActive
is true
, the disabled
attribute will be attached with the Button element and the Button will be disabled.
The above example of v-bind is very basic and straight forward. We will show you a real and practical use of v-bind which is very popular. It's called dynamic class binding -
<div id="Example"> <a v-bind:class="myClass"></a> </div> <script type="text/javascript"> new Vue({ el : "#Example", data : { myClass : 'button' } }); </script>
Well, it's still a basic usage. But let's look at the below example -
<div id="Example"> <a class="button" v-bind:class="{ 'is-success' : isSuccess }"></a> </div> <script type="text/javascript"> new Vue({ el : "#Example", data : { isSuccess : true, } }); </script>
In real life, most of the time we use more than one class on an element. And sometimes we want to render different style in different situation. For this case, Vue.js provides us an awesome mechanism which only applicable for class attribute of all HTML element. You can write maximum two class attribute and one of them is dynamic and the other one is static. In the above example class="button"
is an static class attribute and :class="{ 'is-success' : isSuccess }"
is a dynamic attribute.
If the value of isSuccess
is true
, the class is-active
will be added to the button. But what if you want to include another class which depends on another vue property. This is done with a comma separator -
v-bind:class="{ active: isActive, 'text-danger': hasError }">
Did you notice the enclosing single inverted comma on the class name? Well, general rule of thumb if you use special character other than underscore, you will always want to enclose them within single or double inverted comma.
As I have said, this mechanism is only applicable for class attribute only, so doing something like this is totally crime -
<input type="text" name="" placeholder="Hello" :placeholder="{ 'is-success' : isSuccess }">
The above line won't give you nothing but a broken placeholder which might make your life miserable.
Hey, can you tell me why there's a { and } in the dynamic class attribute? Well, if you notice it's an object. General rule of thumb, the key
is the name of the class and the value
is boolean which determines whether to include the key to the class attribute. So, doing something like this is totally fine -
<div v-bind:class="classObject"></div> data:{ isSuccess : true, classObject : { 'is-success' : this.isSuccess, 'is-disabled' : false, button : true }, }
And this will render as class="is-success button"
You can also use a computed property which returns an object. The following is a complex example -
<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' } } }
You can also pass an array to v-bind directive.
<div v-bind:class="[activeClass, errorClass]"></div> data: { activeClass: 'active', errorClass: 'text-danger' }
This will render as <div class="active text-danger"></div>
One of the coolest part of Vue.js is that it gives you the ability to use inline javascript syntax where you can use Vue property -
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
Here, errorClass
will always be rendered. But the class isActive
will be rendered conditionally. If the activeClass
is true the class isActive
will be included. Otherwise not.
But this seems quite complex and is not readable. But you will always include object within the array which looks simpler than the above and quite readable.
<div v-bind:class="[{ isActive : activeClass }, errorClass]"></div>
So, if the activeClass
becomes true, only then isActive
is included in the class list.
So far, we have been using v-bind to class attribute. One of the good usage of v-bind is on the style attribute. Which gives us a lot more flexibility to write dynamic value.
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> data: { activeColor: 'red', fontSize: 30 }
Here, we are using object inside the v-bind. This way you can dynamically bind style values with any tag you want. Pretty amazing. You now don't need to use jQuery. Notice that we are writing inline javascript statement for fontSize
property. However, if your css property grows in number it looks messy. So it is always a better idea to directly pass an object to style using v-bind.
<div v-bind:style="styleObject"></div> data: { styleObject: { color: 'red', width: '500px' } }
Once again, here styleObject can also be an computed property that returns an object.
You can use Array which is consists of some object which holds the different css property.
<div v-bind:style="[obj1, obj2]" style="background-color:yellow;></div> data:{ obj1:{ width : '100px', 'background-color' : 'red' }, obj2:{ height : '300px', color : 'white' } }
And this will render as <div style="width: 100px; background-color: red; height: 300px; color: white;" style="background-color:yellow;"></div>
And this will give the following output --
If you notice in the above example, we have also written static style property. This is also allowed. But one thing to remember that if you bind the style property with v-bind, all the dynamic css property will override the static css property. And that's why the background-color
didn't changed to yellow.
Well, there's shorthand syntax of v-bind directive. Instead of always writting v-bind:class=""
you can use :class=""
. Means you can ommit the keyword v-bind
. Just prefix the HTML attribute with the colon and Vue will take care the rest of the things.
As we have seen earlier that we can write inline JS statement where we can write Vue property -
<input type="text" :value="myValue + 1"> data : { myValue : 30 }
<input type="text" :value="theValue == myValue"> data : { myValue : 30, theValue : 30, }
<input type="text" :value="theValue > 10 ? 'Yes' : 'No' "> <input type="text" :value="{ Yes : theValue > 10 }"> <input type="text" :value="[theValue > 10 ? 'Yes' : myValue, 'Hello']"> data : { myValue : 30, theValue : 30, }