Basic Usage

Để handle một form trong html, để lấy ra giá trị của các ô input mà người dùng nhập vào, thay vì sử dụng attribute name để đặt tên cho ô input đó thì khi sử dụng Vuejs, chúng ta có thể xử lý form đó một cách rất thuận tiện và dễ dàng.
Bạn có thể sử dụng v-model để tạo ra các ràng buộc dữ liệu hai chiều trên các ô input hoặc textarea hay thậm chí là file. Nó sẽ tự động chọn đúng cách để cập nhật các phần tử dựa trên kiểu nhập. Mặc dù khi sử dụng bạn sẽ thấy có đôi chút magic, nhưng v-model thực sự là một cú pháp không thể thiếu mỗi khi bạn muốn handle một form một cách thuận tiện và ngon lành 😀
Note: v-model sẽ bỏ qua các giá trị ban đầu, “checked” hoặc “selected” attribute được tìm thấy trên bất kì form elements nào. Nó sẽ luôn luôn xử lý các dữ liệu của Vue instance như là những dữ liệu luôn đúng. Bạn nên khai báo giá trị ban đầu ở phía Javascript bên trong các component.
Chúng ta cùng đi vào một vài ví dụ đơn giản với từng loại input cơ bản như sau:

Text

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

Khi đó, mỗi lần giá trị của ô input được nhập, biến message sẽ thay đổi theo, ta chỉ việc gọi this.message là có thể lấy được giá trị đó. Thật đơn giản phải không. Nên nhớ khai báo message ở Vue instance để có thể sử dụng nhé.

new Vue({
  data: {
   message: ' '
  }
})

Multiline text

Tương tự như ô input thường thì ta cũng có thể sử dụng tương tự với textarea :

<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

Checkbox

Đối với single checkbox, sử dụng boolean value:

<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

Hay multiple checkboxes, sử dụng array:

<div id='example-3'>
 <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
 <label for="jack">Jack</label>
 <input type="checkbox" id="john" value="John" v-model="checkedNames">
 <label for="john">John</label>
 <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
 <label for="mike">Mike</label>
 
<span>Checked names: {{ checkedNames }}</span> </div>
new Vue({
 el: '#example-3',
 data: {
   checkedNames: 
 }
})

Radio

<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>

Select

Single select:

<select v-model="selected">
 <option disabled value="">Please select one</option>
 <option>A</option>
 <option>B</option>
 <option>C</option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
 el: '...',
 data: {
   selected: ''
 }
})

Hay multiple select:

<select v-model="selected" multiple>
 <option>A</option>
 <option>B</option>
 <option>C</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
ABC 
Selected: 

Có thể sử dụng kết hợp v-for để render view:

<select v-model="selected">
 <option v-for="option in options" v-bind:value="option.value">
   {{ option.text }}
 </option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
 el: '...',
 data: {
   selected: 'A',
   options: [
     { text: 'One', value: 'A' },
     { text: 'Two', value: 'B' },
     { text: 'Three', value: 'C' }
   ]
 }
})

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.

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.

<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.

<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>

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.

Lời kết

Có một chút lưu ý như sau:
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.

References:

https://vuejs.org/v2/guide/forms.html