DANH MỤC: Vue.js

Bài 9: Form input binding trong Vue.js


Ngoài xử lý sự kiện ra thì Vue.js cũng hỗ trợ chúng ta rất mạnh về phần ràng buộc các input trong form.

1,  Basic Usage.

Trong vue.js bạn có thể sử dụng v-model directive để tạo ra các ràng buộc dữ liệu hai chiều trên các input và textarea element. Và nó sẽ lựa chon đúng cách và cập nhật các element trên các input type. Mặc dù nó có một chú magic, nhưng về cơ bản thì thì v-model là một cú pháp đường dẫn để cập nhật dữ liệu trên các sự kiện của người dùng.

Đối với v-model nó sẽ bỏ qua tất cả các khởi tạo của value, checked hay selected trên các thành phần của form và nó luôn xử lý các dữ liệu có trong Vue instance, chính vì thế bạn nên khai báo các giá trị khởi tạo đó ở trong data scope của Vue instance.

Text

VD: Sử dụng v-model trong Vue.js trên thẻ input.

<div id="app">
    <input type="text" v-model="message" placeholder="Nhập cái gì đó vào đây đi ông bạn!">
    <p>Mesage = {{ message }}</p>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            message: null,
        }
    });
</script>  

Textarea

VD: Sử dụng v-model trên textarea.

<textarea v-model="message" placeholder="Nhập cái gì đó vào đây đi ông bạn!" rows="5" cols="70"></textarea> 
<p>Mesage = {{ message }}</p>

Đối với thẻ tetarea thì bạn không thể bind dữ liệu bằng cách <textarea>{{ message }}</textarea> được, mà bạn phải sử dụng cú pháp v-model như ví dụ trên.

Checkbox 

VD: checkbox đơn

<div id="app">
    <input type="checkbox" v-model="checked">
    <label>{{ checked }}</label>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            checked: false,
        }
    });
</script>   

VD: multiple checkbox.

<div id="app">
    <input type="checkbox" id="php" value="PHP" v-model="checked">
    <label for="php">PHP</label>
    <input type="checkbox" id="js" value="JS" v-model="checked">
    <label for="js">JS</label>
    <input type="checkbox" id="nodejs" value="Node.js" v-model="checked">
    <label for="nodejs">Node.js</label>
    <p>Các input đã check: {{ checked }}</p>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            checked: [],
        }
    });
</script>

Radio

VD:

<div id="app">
    <input type="radio" id="php" name="language" value="PHP" v-model="checked">
    <label for="php">PHP</label>
    <input type="radio" id="js" name="language" value="JS" v-model="checked">
    <label for="js">JS</label>
    <input type="radio" id="nodejs" name="language" value="Node.js" v-model="checked">
    <label for="nodejs">Node.js</label>
    <p>Radio đã check: {{ checked }}</p>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            checked: null,
        }
    });
</script>

Select

VD:

<div id="app">
    <select name="language" v-model="selected">
    <option value="" disabled="true" selected>Chọn...</option>
        <option value="PHP">PHP</option>
        <option value="JS">JS</option>
        <option value="Node.js">Node.js</option>
        <option value="Vue.js">Vue.js</option>
    </select>
    <p>Select đã chọn: {{ selected }}</p>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            selected: '',
        }
    });
</script>   

Nếu như giá trị khởi tạo của bạn không khớp với một option nào thì nó sẽ kích hoạt trạng thái unselected, nhưng điều này cũng đồng nghĩa với việc nó sẽ không hoạt động được trên IOS vì trên IOS không hỗ trợ trường hợp thay đổi này. Chính vì thế bạn cần thêm một option ở trạng thái disable (như trong ví dụ trên) để khác phục hạn chế này.

VD: Còn đối với multi select.

<div id="app">
<select name="language" v-model="selected" multiple>
        <option value="" disabled="true" selected>Chọn...</option>
        <option value="PHP">PHP</option>
        <option value="JS">JS</option>
        <option value="Node.js">Node.js</option>
        <option value="Vue.js">Vue.js</option>
    </select>
    <p>Select đã chọn: {{ selected }}</p>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            selected: [],
        }
    });
</script>

Và đương nhiên là bạn cũng có thể kết hợp nó với v-for để render ra dữ liệu cho select element.

<div id="app">
    <select name="language" v-model="selected">
        <option v-for="item in option" v-bind:value="item.value">
            {{ item.text }}
        </option>
    </select>
    <p>Select đã chọn: {{ selected }}</p>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            selected: 'js',
            option: [
                { text: 'PHP', value: 'php' },
                { text: 'Node.js', value: 'node' },
                { text: 'Javascript', value: 'js' },
                { text: 'Vue.js', value: 'vuejs' },
            ],
        }
    });
</script>

2, Value bindings.

Đối với các thành phần là radio hoặc select option thì v-model thường sẽ là chuỗi tĩnh. còn nếu thành phần là checkbox thì thường sẽ là giá trị boolean true false. Nhưng đôi lúc nếu như bạn muốn sử các thuộc tính có giá trị động trên vue instance thì bạn có thể sử dụng v-bind directive để thực hiện điều đó.

Ví dụ đối với checkbox element.

<div id="app">
    <input type="checkbox" v-model="toggle" v-bind:true-value="yes" v-bind:false-value="no">
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            toggle: true,
            yes: true,
            no: false,
        }
    });
</script>

Trong trường hợp trên nếu như giá trị của toggle mà bằng giá trị của yes thì checkbox sẽ checked và ngược lại giá trị của toggle mà bằng giá trị của no thì checkbox sẽ unchecked.

Và điều này cũng xảy ra tương tự đối với radio và selected.

VD: Đối với radio.

<div id="app">
    <input type="checkbox" v-model="pick" v-bind:value="a">
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            pick: 'b',
            a: 'b'
        }
    });
</script>

radio sẽ checked khi giá trị của pick bằng với giá trị của a.

VD: Đối với select.

<div id="app">
    <select v-model="selected">
    <option v-bind:value="{value : 'php'}">{{ item.text }}</option>
    </select>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            selected: { value : 'php'}
        }
    });
</script>

Option sẽ được selected nếu giá trị vủa selected.value = với giá trị vủa value.

3, Modifiers.

.lazy

Thông thường thì v-model sẽ tự động đồng bộ trong quá trình soạn thảo (chỉ trừ các ngôn ngữ IME - xem ở phần lời kết nhé!), nhưng nếu bạn muốn thay đổi trạng thái đó thì bạn có thể sử dụng .lazy modifier để chuyển đổi nó sang trạng thái change event (có nghĩa là khi input thay đổi thì dữ liệu mới tiến hành đồng bộ).

VD:

<div id="app">
    <input type="text" v-model.lazy="message" placeholder="nhập dữ liệu...">
    <p>message = {{ message }}</p>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            message: null
        }
    });
</script>

.number

Nếu như bạn muốn ràng buộc dữ liệu đầu vào của input chỉ được phép là số thì hãy sử dụng modifier .number để ràng buộc điều này.

VD:

<div id="app">
    <input type="text" v-model.number="message" placeholder="nhập dữ liệu...">
    <p>message = {{ message }}</p>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            message: null
        }
    });
</script>

Điều này sẽ vô cùng có ích, bời ngay cả các input mà có type bằng number (type=number) nó cũng luôn trả về giá trị là 1 string.

.trim

Còn nếu như bạn muốn loại bỏ những khoảng trắng ở hai đầu của dữ liệu thì .trim modifier là một lựa chọn cực kỳ tuyệt vời.

VD:

<div id="app">
    <input type="text" v-model.trim="message" placeholder="nhập dữ liệu...">
    <p>message = {{ message }}</p>
</div>
<script src="https://unpkg.com/vue@2.4.2" type="text/javascript"></script>
<script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            message: null
        }
    });
</script>

4, v-model với component.

Tham thế bạn, phần này mình chỉ viết cho đẹp đội hình thôi, còn nếu như bạn muốn tìm hiểu có thể tìm nó ở trong bài component trong Vue.js.

5, Lời kết.

Các bạn lưu ý dùm mình:

v-model chỉ hoạt động tốt trên các ngôn ngữ dạng latinh thôi, còn nếu như bạn sủ dụng các dạng ngôn ngữ thuộc loại IME (là loại dành cho mấy ngôn ngữ nhật bản, trung quốc, hàn quốc, ...) thì v-model nó sẽ không thể đồng bộ hóa dữ liệu trong quá trình soạn thảo hoặc changing được, và để khắc phục nhược điểm đó bạn có thể sử dụng các directive sự kiện.

Nguồn: Toidicode.com

Thông tin tác giả

Vũ Thanh Tài

Vũ Thanh Tài

The best way to learn is to share

Hãy tham gia group facebook để cùng giao lưu chia sẻ kiến thức! Tham Gia