VueJS – Binding

Bài này chúng ta sẽ học cách thay đổi các giá trị attributes, style hay class của HTML với v-bind và ràng buộc dữ liệu 2 chiều với v-model của VueJS.

v-bind

Ví dụ

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         {{title}}<br/>
         <a href = "hreflink" target = "_blank"> Click Me </a> <br/>
         <a href = "{{hreflink}}" target = "_blank">Click Me </a>  <br/>
         <a v-bind:href = "hreflink" target = "_blank">Click Me </a>   <br/>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               title : "DATA BINDING",
               hreflink : "http://www.google.com"
            }
         });
      </script>
   </body>
</html>

Ở ví dụ trên, Chúng ta hiển thị ra title và 3 link. Giá trị của chúng được lấy từ data objects.

Khi kiểm tra kết quả trên trình duyệt, Chúng ta thấy 2 link đầu tiên đã không hiển thị đúng href.

Như vậy, muốn gắn giá trị vào attributes của HTML chúng ta cần dùng v-bind.

<a v-bind:href = "hreflink" target = "_blank">Click Me </a>

Hay có thể viết gọn lại là:

<a :href = "hreflink" target = "_blank">Click Me </a>

Binding HTML Classes

Để bind HTML class, bạn cần dùng v-bind:class.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <style>
         .active {
            background: red;
         }
      </style>
      <div id = "classbinding">
         <div v-bind:class = "{active:isactive}"><b>{{title}}</b></div>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#classbinding',
            data: {
               title : "CLASS BINDING",
               isactive : true
            }
         });
      </script>
   </body>
</html>

Ở đây, có thẻ div với v-bind:class = “{active:isactive}”.

isactive nhận 2 giá trị true hoặc false. Trong data, isactive được gán giá trị là true. Nó sẽ gắn class active vào thẻ div. Chúng ta cũng tạo style cho class active có background là red.

Kết quả

Bây giờ chúng ta thay isactive thành false như code bên dưới.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <style>
         .active {
            background: red;
         }
      </style>
      <div id = "classbinding">
         <div v-bind:class = "{active:isactive}"><b>{{title}}</b></div>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#classbinding',
            data: {
               title : "CLASS BINDING",
               isactive : false
            }
         });
      </script>
   </body>
</html>

Kết quả của chúng ta đã không còn class active trong thẻ div.

Chúng ta cũng có thể gán nhiều class vào tag HTML với thuộc tính v-bind.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <style>
         .info {
            color: #00529B;
            background-color: #BDE5F8;
         }
         div {
            margin: 10px 0;
            padding: 12px;
         }
         .active {
            color: #4F8A10;
            background-color: #DFF2BF;
         }
         .displayError{
            color: #D8000C;
            background-color: #FFBABA;
         }
      </style>
      <div id = "classbinding">
         <div class = "info"  v-bind:class = "{ active: isActive, 'displayError': hasError }">
            {{title}}
         </div>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#classbinding',
            data: {
               title : "This is class binding example",
               isActive : false,
               hasError : false
            }
         });
      </script>
   </body>
</html>

Ở ví dụ trên, thẻ div có class = “info”. Và isActive, hasError sẽ thêm class activedisplayError nếu giá trị là true.

Kết quả

Thực hiện ví dụ trên với isActive là true.

Chúng ta thấy có 2 class trong thẻ div. Thực hiện lại ví dụ với isActive là false và hasError là true.

Chúng ta cũng có thể sử dụng mảng để thêm nhiều class vào DOM HTML.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <style>
         .info {
            color: #00529B;
            background-color: #BDE5F8;
         }
         div {
            margin: 10px 0;
            padding: 12px;
            font-size : 25px;
         }
         .active {
            color: #4F8A10;
            background-color: #DFF2BF;
         }
         .displayError{
            color: #D8000C;
            background-color: #FFBABA;
         }
      </style>
      <div id = "classbinding">
         <div v-bind:class = "[infoclass, errorclass]">{{title}}</div>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#classbinding',
            data: {
               title : "This is class binding example",
               infoclass : 'info',
               errorclass : 'displayError'
            }
         });
      </script>
   </body>
</html>

Kết quả

Chúng ta cũng có thể thêm class dựa vào điều kiện như những ví dụ đầu.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <style>
         .info {
            color: #00529B;
            background-color: #BDE5F8;
         }
         div {
            margin: 10px 0;
            padding: 12px;
            font-size : 25px;
         }
         .active {
            color: #4F8A10;
            background-color: #DFF2BF;
         }
         .displayError{
            color: #D8000C;
            background-color: #FFBABA;
         }
      </style>
      <div id = "classbinding">
         <div v-bind:class = "[isActive ? infoclass : '', haserror ? errorclass : '']">{{title}}</div>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#classbinding',
            data: {
               title : "This is class binding example",
               infoclass : 'info',
               errorclass : 'displayError',
               isActive : true,
               haserror : false
            }
         });
      </script>
   </body>
</html>

Chúng ta có isActivehaserror sẽ có giá trị true hay false, quyết định class có trong thẻ div hay không.

<div v-bind:class = "[isActive ? infoclass : '', haserror ? errorclass : '']">{{title}}</div>

Nếu chúng ta thay đổi isActive thành false và haserror thành true.

Bây giờ, chúng ta sẽ sử dụng v-bind trong components. Ví dụ chúng ta thêm class vào component template như ví dụ bên dưới.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <style>
         .info {
            color: #00529B;
            background-color: #BDE5F8;
         }
         div {
            margin: 10px 0;
            padding: 12px;
            font-size : 25px;
         }
         .active {
            color: #4F8A10;
            background-color: #DFF2BF;
         }
         .displayError{
            color: #D8000C;
            background-color: #FFBABA;
         }
      </style>
      <div id = "classbinding">
         <new_component class = "active"></new_component>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#classbinding',
            data: {
               title : "This is class binding example",
               infoclass : 'info',
               errorclass : 'displayError',
               isActive : false,
               haserror : true
            },
            components:{
               'new_component' : {
                  template : '<div class = "info">Class Binding for component</div>'
               }
            }
         });
      </script>
   </body>
</html>

Chúng ta thấy có 2 class trong thẻ div như hình sau.

Chúng ta thêm biến với giá trị true/false để thêm class hay không.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <style>
         .info {
            color: #00529B;
            background-color: #BDE5F8;
         }
         div {
            margin: 10px 0;
            padding: 12px;
            font-size : 25px;
         }
         .active {
            color: #4F8A10;
            background-color: #DFF2BF;
         }
         .displayError{
            color: #D8000C;
            background-color: #FFBABA;
         }
      </style>
      <div id = "classbinding">
         <new_component v-bind:class = "{active:isActive}"></new_component>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#classbinding',
            data: {
               title : "This is class binding example",
               infoclass : 'info',
               errorclass : 'displayError',
               isActive : false,
               haserror : true
            },
            components:{
               'new_component' : {
                  template : '<div class = "info">Class Binding for component</div>'
               }
            }
         });
      </script>
   </body>
</html>

isActive đang có giá trị là false nên chúng ta chỉ có 1 class trong thẻ div là info.

Binding Inline Styles

Tiếp theo chung ta học cách thêm các style vào tags HTML.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <div v-bind:style = "{ color: activeColor, fontSize: fontSize + 'px' }">{{title}}</div>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               title : "Inline style Binding",
               activeColor: 'red',
               fontSize :'30'
            }
         });
      </script>
   </body>
</html>

Trong ví dụ trên, chúng ta đã thêm các thuộc tính color, fontSize từ data.

<div v-bind:style = "{ color: activeColor, fontSize: fontSize + 'px' }">{{title}}</div>
data: {
   title : "Inline style Binding",
   activeColor: 'red',
   fontSize :'30'
}

Chúng ta cũng có thể thêm tất cả style vào một biến và gắn vào thẻ div như sau.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <div v-bind:style = "styleobj">{{title}}</div>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               title : "Inline style Binding",
               styleobj : {
                  color: 'red',
                  fontSize :'40px'
               }
            }
         });
      </script>
   </body>
</html>

v-model

Tiếp theo chúng ta tìm hiểu về v-model. Tạo sự ràng buộc giữ liệu 2 chiều từ input và textarea với giá trị biến trong Vue instance.

Ví dụ

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <h3>TEXTBOX</h3>
         <input  v-model = "name" placeholder = "Enter Name" />
         <h3>Name entered is : {{name}}</h3>
         <hr/>
         <h3>Textarea</h3>
         <textarea v-model = "textmessage" placeholder = "Add Details"></textarea>
         <h1><p>{{textmessage}}</p></h1>
         <hr/>
         <h3>Checkbox</h3>
         <input type = "checkbox" id = "checkbox" v-model = "checked"> {{checked}}
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               name:'',
               textmessage:'',
               checked : false
            }
         });
      </script>
   </body>
</html>

Những gì chúng ta nhập vào input sẽ thay đổi giá trị name trong data của Vue instance và hiển thị lại trình duyệt thông qua {{name}}. Tương tự cho textarea và checkbox.

Radio và Select

ví dụ

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <h3>Radio</h3>
         <input type = "radio" id = "black" value = "Black" v-model = "picked">Black
         <input type = "radio" id = "white" value = "White" v-model = "picked">White
         <h3>Radio element clicked : {{picked}} </h3>
         <hr/>
         <h3>Select</h3>
         <select v-model = "languages">
            <option disabled value = "">Please select one</option>
            <option>Java</option>
            <option>Javascript</option>
            <option>Php</option>
            <option>C</option>
            <option>C++</option>
         </select>
         <h3>Languages Selected is : {{ languages }}</h3>
         <hr/>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               picked : 'White',
               languages : "Java"
            }
         });
      </script>
   </body>
</html>

Kết quả

Một số tùy chọn trong v-model

Bạn có thể sử dụng các tùy chỉnh v-model như trim, number, lazy.

Ví dụ

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <span style = "font-size:25px;">Enter Age:</span> <input v-model.number = "age" type = "number">
         <br/>
         <span style = "font-size:25px;">Enter Message:</span> <input v-model.lazy = "msg">
         <h3>Display Message : {{msg}}</h3>
         <br/>
         <span style = "font-size:25px;">Enter Message : </span><input v-model.trim = "message">
         <h3>Display Message : {{message}}</h3>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               age : 0,
               msg: '',
               message : ''
            }
         });
      </script>
   </body>
</html>

Number : Chỉ chấp nhận dữ liệu dạng số.

Lazy : Chỉ thực hiện thay đổi khi nhập xong dữ liệu (Khi rời khỏi input).

Trim : Loại bỏ dấu cách ở vị trí bắt dầu và kết thúc.