表單類控制項承載了一個網頁數據的錄入與交互,本章將介紹如何使用指令v-model完成表單的數據雙向綁定。 ...
本篇目錄:
表單類控制項承載了一個網頁數據的錄入與交互,本章將介紹如何使用指令v-model
完成表單的數據雙向綁定。
6.1 基本用法
表單控制項在實際業務較為常見,比如單選、多選、下拉選擇、輸入框等,用它們可以完成數據的錄入、校驗、提交等。
Vue.js提供了v-model
指令,用於在表單類元素上雙向綁定數據,例如在輸入框上使用時,輸入的內容會實時映射到綁定的數據上。
例如下麵的例子:
1 <div id="app"> 2 <input type="text" v-model="message" placeholder="請輸入..."> 3 <p>輸入的內容是:{{message}}</p> 4 </div> 5 6 <script> 7 var app = new Vue({ 8 el: "#app", 9 data: { 10 message: "" 11 } 12 }); 13 </script>
在輸入框輸入的同時,{{message}}
也會實時將內容渲染在視圖中。
如圖6-1所示:

對於文本域<textarea>
也是同樣的用法:
1 <div id="app"> 2 <textarea v-model="text" placeholder="請輸入..."></textarea> 3 <p>輸入的內容是:</p> 4 <p style="white-space: pre;">{{text}}</p> 5 </div> 6 7 <script> 8 var app = new Vue({ 9 el: "#app", 10 data: { 11 text: "" 12 } 13 }); 14 </script>
提示:
提示v-model
後,表單控制項顯示的值只依賴所綁定的數據,不再關心初始化時的value
屬性,對於在<textarea></textarea>
之間插入的值,也不會生效。
使用v-model
時,如果是用中文輸入法輸入中文,一般在沒有選定片語前,也就是在拼音階段,Vue是不會更新數據的,當敲下漢字時才會觸發鞥新。
如果希望總是實時更新,可以用@input
來替代v-model
。
事實上,v-model
也是一個特殊的語法糖,只不過它會在不同的表單上智能處理。
例如下麵的示例:
1 <div id="app"> 2 <input type="text" @input="handleInput" placeholder="請輸入..."> 3 <p>輸入的內容是:{{message}}</p> 4 </div> 5 6 <script> 7 var app = new Vue({ 8 el: "#app", 9 data: { 10 message: "" 11 }, 12 methods: { 13 handleInput: function(event) { 14 this.message = event.target.value; 15 } 16 } 17 }); 18 </script>
來看看更多的表單控制項。
單選按鈕:
單選按鈕在單獨使用時,不需要v-model
,直接使用v-bind
綁定一個布爾類型的值,為true
時選中,為false
時不選。
例如:
1 <div id="app"> 2 <input type="radio" :checked="picked"> 3 <label>單選按鈕</label> 4 </div> 5 6 <script> 7 var app = new Vue({ 8 el: "#app", 9 data: { 10 picked: true 11 } 12 }); 13 </script>
如果是組合使用來實現互斥選擇的效果,就需要v-model
配合value
來使用:
1 <div id="app"> 2 <input type="radio" v-model="picked" value="html" id="html"> 3 <label for="html">HTML</label> 4 5 <input type="radio" v-model="picked" value="js" id="js"> 6 <label for="js">JavaScript</label> 7 8 <input type="radio" v-model="picked" value="css" id="css"> 9 <label for="css">CSS</label> 10 11 <p>您選擇的是:{{picked}}</p> 12 </div> 13 14 <script> 15 var app = new Vue({ 16 el: "#app", 17 data: { 18 picked: "js" 19 } 20 }); 21 </script>
數據picked
的值與表單按鈕的value
值一致時,就會選中該項,所以當前狀態下選中的是第二項。
如圖6-2所示:

覆選框:
覆選框也分單獨使用和組合使用,不過用法稍與單選不同。
覆選框單獨使用時,也是用v-model
來綁定一個布爾值。
例如:
1 <div id="app"> 2 <input type="checkbox" v-model="checked" id="checked"> 3 <label for="checked">選擇狀態:{{checked}}</label> 4 </div> 5 6 <script> 7 var app = new Vue({ 8 el: "#app", 9 data: { 10 checked: false 11 } 12 }); 13 </script>
在勾選時,數據checked
的值改為了true
,<label>
中渲染的內容也會更新。
組合使用時,也是v-model
與value
一起,多個勾選框都綁定到同一個數組類型的數據,value
的值在數據當中,就會選中這一項。
這一過程也是雙向的,在勾選時,value
的值也會自動push
到這個數組中。
實例代碼如下:
1 <div id="app"> 2 <input type="checkbox" v-model="checked" value="html" id="html"> 3 <label for="html">HTML</label> 4 <br> 5 <input type="checkbox" v-model="checked" value="js" id="js"> 6 <label for="js">JavaScript</label> 7 <br> 8 <input type="checkbox" v-model="checked" value="css" id="css"> 9 <label for="css">CSS</label> 10 <br> 11 <p>你選擇的是:{{checked}}</p> 12 </div> 13 14 <script> 15 var app = new Vue({ 16 el: "#app", 17 data: { 18 checked: ["html", "css"] 19 } 20 }); 21 </script>
當前狀態下的結果如圖6-3所示:

選擇列表:
選擇列表就是下拉選擇器,也是常見的表單控制項,同樣也分為單選和多選兩種方式。
先看一下單選的示例代碼:
1 <div id="app"> 2 <select v-model="selected"> 3 <option>html</option> 4 <option value="js">JavaScript</option> 5 <option>css</option> 6 </select> 7 <p>你選擇的是:{{selected}}</p> 8 </div> 9 10 <script> 11 var app = new Vue({ 12 el: "#app", 13 data: { 14 selected: "html" 15 } 16 }); 17 </script>
<option>
是備選項,如果含有value
屬性,v-model
就會優先匹配value
的值;
如果沒有,就會直接匹配<option>
的text
。
比如選中第二項時,selected
的值為js
,而不是JavaScript
。
給<select>
添加屬性multiple
就可以多選了,此時v-model
綁定的是一個數組,與覆選框用法類似。
實例代碼如下:
1 <div id="app"> 2 <select v-model="selected" multiple> 3 <option>html</option> 4 <option value="js">JavaScript</option> 5 <option>css</option> 6 </select> 7 <p>你選擇的是:{{selected}}</p> 8 </div> 9 10 <script> 11 var app = new Vue({ 12 el: "#app", 13 data: { 14 selected: ["html", "js"] 15 } 16 }); 17 </script>
在業務中,<option>
經常用v-for
動態輸出,value
和text
也是用v-bind
來動態輸出的。
例如:
<div id="app"> <select v-model="selected"> <option v-for="item in options" :value="item.value">{{item.text}}</option> </select> <p>你選擇的是:{{selected}}</p> </div> <script> var app = new Vue({ el: "#app", data: { options: [ {text:"HTML", value:"html"}, {text:"JavaScript", value:"js"}, {text:"CSS", value:"css"}, ], selected: "html" } }); </script>
雖然用選擇列表<select>
控制項可以很簡單地完成下拉選擇的需求,但是在實際業務中反而不常用,因為它的樣式依賴平臺和瀏覽器,無法統一,也不太美觀,功能也受限,,比如不支持搜索,所以常見的解決方案是用<div>
moi一個類似的控制項。
當閱讀完第7章組件的內容後,可以嘗試編寫一個下拉選擇器的通用組件。
6.2 綁定值
上一節介紹的單選按鈕、覆選框和選擇列表在單獨使用或單選的模式下,v-model
綁定的值是一個靜態字元串或布爾值。
但在業務中,有時需要綁定一個動態的數據,這時可以用v-bind
來實現。
單選按鈕:
1 <div id="app"> 2 <input type="radio" v-model="picked" :value="value"> 3 <label>單選按鈕</label> 4 <p>{{picked}}</p> 5 <p>{{value}}</p> 6 </div> 7 8 <script> 9 var app = new Vue({ 10 el: "#app", 11 data: { 12 picked: false, 13 value: 123 14 } 15 }); 16 </script>
在選中時,app.picked===app.value
,值都是123
。
覆選框:
1 <div id="app"> 2 <input type="checkbox" v-model="toggle" :true-value="value1" :false-value="value2"> 3 <label>覆選框</label> 4 <p>{{toggle}}</p> 5 <p>{{value1}}</p> 6 <p>{{value2}}</p> 7 </div> 8 9 <script> 10 var app = new Vue({ 11 el: "#app", 12 data: { 13 toggle: false, 14 value1: "a", 15 value2: "b" 16 } 17 }); 18 </script>
勾選時,app.toggle===app.value1
;
未勾選時,app.toggle===app.value2
。
選擇列表:
1 <div id="app"> 2 <select v-model="selected"> 3 <option :value="{number:123}">123</option> 4 </select> 5 {{selected.number}} 6 </div> 7 8 <script> 9 var app = new Vue({ 10 el: "#app", 11 data: { 12 selected: "" 13 } 14 }); 15 </script>
當選中時,app.selected
是一個Object,所以app.selected.number===123
。
6.3 修飾符
與事件的修飾符類似,v-model
也有修飾符,用於控制數據同步的時機。
.lazy:
在輸入框中,v-model
預設是在input
事件中同步輸入框的數據(除了提示中介紹的中文輸入法情況外)。
使用修飾符.lazy
會轉變為在change
事件中同步,示例代碼如下:
1 <div id="app"> 2 <input type="text" v-model.lazy="message"> 3 <p>{{message}}</p> 4 </div> 5 6 <script> 7 var app = new Vue({ 8 el: "#app", 9 data: { 10 message: "" 11 } 12 }); 13 </script>
這是,message
並不是實時改變的,而是在失焦或按回車時才更新。
.number:
使用修飾符.number
可以將輸入轉換為Number類型,否則雖然你輸入的是數字,但它的類型其實是String。
比如在數字輸入框時會比較有用,示例代碼如下:
1 <div id="app"> 2 <input type="number" v-model.number="message"> 3 <p>{{typeof message}}</p> 4 </div> 5 6 <script> 7 var app = new Vue({ 8 el: "#app", 9 data: { 10 message: 123 11 } 12 }); 13 </script>
.trim:
修飾符.trim
可以自動過濾輸入的首尾空格,示例代碼如下:
1 <div id="app"> 2 <input type="text" v-model.trim="message"> 3 <p>{{message}}</p