通過(guò)前面的學(xué)習(xí),我們可以順利的在Vue中將數(shù)據(jù)源渲染到HTML的DOM元素中,但很多時(shí)候我們希望能控制數(shù)據(jù)源。也就是數(shù)據(jù)綁定,并且與其通訊。簡(jiǎn)單的說(shuō),怎么在Vue中實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。這種場(chǎng)景一般都是在表單的操作情景中。在Vue中可以使用v-model
的指令來(lái)實(shí)現(xiàn)。不過(guò)這篇文章我們只是來(lái)學(xué)習(xí)v-model
指令的使用,但不探究Vue數(shù)據(jù)雙向綁定的原理。如果你對(duì)原理方面感興趣,可以閱讀這篇文章。
基礎(chǔ)用法
在Vue中,通過(guò){{}}
或v-text
的方式,可以將數(shù)據(jù)源中的數(shù)據(jù)渲染到DOM元素中。(學(xué)習(xí)視頻分享:vue視頻教程)
比如:
<!-- Template --> <h1>{{ message }}</h1> let app = new Vue({ el: '#app', data: { message: 'Hello W3cplus! (^_^)' } })
基于上面的示例,咱們修改一下需求,我們想通過(guò)一個(gè)<input>
的輸入來(lái)修改{{message}}
。這個(gè)時(shí)候我們就需要使用到v-model
。先來(lái)看示例,再聊v-model
。在上面示例的基礎(chǔ)上添加一個(gè)input
,修改后的模板代碼如下:
<!-- Template --> <div id="app"> <div> <input type="text" v-model="message" placeholder="Hello W3cplus!(^_^)" /> </div> <h1>{{ message }}</h1> </div>
從效果中可以看出,修改input
的value
值,對(duì)應(yīng)的h1
元素的內(nèi)容也修改了。這種效果就是數(shù)據(jù)雙向綁定的效果。
而這里關(guān)鍵點(diǎn)就是使用了v-model
指令。在Vue中,可以使用v-model
指令在表單控件元素上創(chuàng)建雙向數(shù)據(jù)綁定。它會(huì)根據(jù)控制類(lèi)型自動(dòng)選取正確的方法來(lái)更新元素。盡管有些神奇,但v-model
本質(zhì)上不過(guò)是語(yǔ)法糖,它負(fù)責(zé)監(jiān)聽(tīng)用戶的輸入事件以更新數(shù)據(jù),并特別處理一些極端的例子。
注意:
v-model
會(huì)忽略所有表單元素的value
、checked
、selected
特性的初始值。因?yàn)樗鼤?huì)選擇Vue實(shí)例數(shù)據(jù)來(lái)作為具體的值。你應(yīng)該通過(guò)JavaScript在組件的data
選項(xiàng)中聲明初始值。
在Vue中,v-model
主要是用于表單控件上。那么接下來(lái),咱們來(lái)看看v-model
在常見(jiàn)的表單控件上是怎么使用的。
單行文本輸入框
前面演示的示例其實(shí)就是單行文本輸入框的效果。input
上通過(guò)v-model
綁定Vue的數(shù)據(jù)源的值。當(dāng)input
輸入值一旦發(fā)生變更時(shí),數(shù)據(jù)也會(huì)相應(yīng)發(fā)生變化,從而元素渲染的插值也會(huì)做出相應(yīng)變化。
這里的data
可以是object
或者function
,但組件的data
只能是function
,這是因?yàn)榻M件內(nèi)各自擁有自己的data
,而非共用的關(guān)系。不過(guò)今天我們不看組件中的數(shù)據(jù)雙向綁定,只是簡(jiǎn)單的看表單控件方面的。不跑題了,回到input
框中來(lái)。我們一般在模板中像下面這樣寫(xiě)代碼:
<!-- Template --> <div id="app"> <div> <input type="text" v-model="message" placeholder="Hello W3cplus!(^_^)" /> </div> <h1>{{ message }}</h1> </div>
同樣的,在Vue實(shí)例中,需要指定data
,我們這個(gè)示例是指message
:
let app = new Vue({ el: '#app', data: { message: 'Hello W3cplus! (^_^)' } })
刷新你的瀏覽器,當(dāng)你修改input
的輸入值時(shí),對(duì)應(yīng)的可以看到h1
元素內(nèi)容的同步變化,效果如下圖所示:
多行文本域
多行文本域textarea
和input
非常的類(lèi)似。比如把上面示例中的input
換面textarea
表單元素,同樣的將v-model="message"
綁定在textarea
元素上。模板代碼像下面這樣:
<!-- Template --> <div id="app"> <div> <textarea v-model="message" cols="30" rows="5"></textarea> </div> <h2>{{ message }}</h2> </div>
咱們?cè)?code>textarea中修改內(nèi)容,對(duì)應(yīng)的h2
也會(huì)有變化:
小結(jié)一下:當(dāng)使用文本input
(包括email
,number
等)或textarea
時(shí),v-model="varName"
等價(jià)于:value="varName" @input="e => varName = e.target.value"
。這意味著每次輸入完成后的varName
將被更新為輸入的值,然后輸入的值被設(shè)置為varName
。正常的select
元素也會(huì)像這樣,盡管multiple
多項(xiàng)選擇有所不同。
在文本區(qū)域插值 (
<textarea></textarea>
) 并不會(huì)生效,應(yīng)用v-model
來(lái)代替。
復(fù)選框
在Vue中的復(fù)選框通過(guò)v-model
綁定數(shù)據(jù)源,并不和我們Web表單中的復(fù)選框一樣。比如下面的示例:
<!-- Template --> <div> <input type="checkbox" v-model="checked" id="checkbox" /> <label for="checkbox">{{checked}}</label> </div> // JavaScript let app = new Vue({ data: { checked: false } })
刷新瀏覽器,當(dāng)復(fù)選框選中的時(shí)候,checked
的值false
就變成了true
。如下圖所示:
不知道你跟我是不是同樣的好奇,如果input
復(fù)選框設(shè)置了checked
(默認(rèn)選中),會(huì)不會(huì)刷新瀏覽器,checked
的值會(huì)不會(huì)變成true
。從實(shí)戰(zhàn)來(lái)看,是不會(huì)有變化的,只有選中之后,false
才會(huì)變成true
。另外再試一個(gè)效果,如果checked
默認(rèn)值不是false
,是任何字符串,看看是什么效果?
是不是很神奇,雖然默認(rèn)選中,并且點(diǎn)擊之后就在false
和true
之間切換。
上面的示例,咱們只使用單個(gè)復(fù)選框,從效果上告訴我們v-model
會(huì)將其視為布爾值,并且會(huì)忽略該value
。而且:
<input type="checkbox" value="foo" v-model="isChecked" />
將和下面的代碼相同:
<input type="checkbox" value="foo" :checked="!!isChecked" @change="e => isChecked = e.target.checked" />
如果想要它是非布爾值,可以使用true-value
和false-value
屬性,它控制當(dāng)選擇復(fù)選框時(shí),模型將被設(shè)置成什么值。
<input type="checkbox" value="foo" v-model="isChecked" true-value="1" false-value="0">
與以下代碼相同
<input type="checkbox" value="foo" :checked="isChecked =='1'" @change="e => isChecked = e.target.checked?'1':'0'">
單一復(fù)選框的情況差不多就是這樣。如果有多個(gè)復(fù)選框共享一個(gè)數(shù)據(jù)源(v-model
指定的值),那么這些復(fù)選框?qū)⑻畛湟粋€(gè)數(shù)組,其值為所有勾選的復(fù)選框,但一定要在數(shù)據(jù)源中指定數(shù)據(jù)是一個(gè)數(shù)組類(lèi)型,否則會(huì)產(chǎn)生一些奇怪的現(xiàn)象。來(lái)看一個(gè)多選項(xiàng)的示例:
<!-- Template --> <div> <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> </div> <div>選中的值:{{checkedNames}}</div> // JavaScript var app = new Vue({ el: '#app', data: { checkedNames: [] } })
效果如下:
當(dāng)我們使用多個(gè)復(fù)選框時(shí),true-value
和false-value
屬性不再有效。同時(shí)在模板中像上面示例使用方式,很難保證一致性,所以最好的方式是將一些邏輯移到組件的方法上。不過(guò)我們這節(jié)并不介紹怎么應(yīng)用到組件中,因?yàn)槲覀冞€沒(méi)有學(xué)習(xí)Vue的組件怎么創(chuàng)建。如果你感興趣的話,可以觀注后續(xù)更新的內(nèi)容,我們將會(huì)花一節(jié)內(nèi)容來(lái)看看怎么完成自定義的復(fù)選框組件。
單選按鈕
v-model
在單選按鈕上的使用,咱們先來(lái)上實(shí)例代碼吧:
<!-- Template --> <div id="app"> <div> <input type="radio" v-model="selected" value="CSS" id="css"/> <label for="css">CSS</label> <input type="radio" v-model="selected" value="HTML" id="html"/> <label for="html">HTML</label> <input type="radio" v-model="selected" value="JavaScript" id="javascript"/> <label for="javascript">JavaScript</label> <br> <div>你最喜歡的是:{{selected}}</div> </div> </div> // JavaScript var app = new Vue({ el: '#app', data: { selected: null } })
更新瀏覽器,看到的效果如下:
選擇框
v-model
在選擇框上的使用,可以運(yùn)用在單項(xiàng)選擇框和多項(xiàng)選擇框,不同的是,多項(xiàng)選擇框在數(shù)據(jù)源中應(yīng)該是一個(gè)數(shù)組。比如下面的示例:
<!-- Template --> <div id="app"> <h1>選擇框</h1> <div> <select v-model="selected"> <option disabled value="">請(qǐng)選擇</option> <option>CSS</option> <option>HTML</option> <option>JavaScript</option> </select> <span>請(qǐng)選擇: {{ selected }}</span> </div> <div> <select v-model="multipleSelected" multiple> <option>CSS</option> <option>HTML</option> <option>JavaScript</option> <option>PHP</option> </select> <span>請(qǐng)選擇:{{multipleSelected}}</span> </div> </div> // JavaScript var app = new Vue({ el: '#app', data: { selected: null, multipleSelected: [] } })
效果如下:
如果 v-model
表達(dá)初始的值不匹配任何的選項(xiàng),<select>
元素就會(huì)以”未選中”
的狀態(tài)渲染。在 iOS 中,這會(huì)使用戶無(wú)法選擇第一個(gè)選項(xiàng),因?yàn)檫@樣的情況下,iOS 不會(huì)引發(fā) change
事件。因此,像以上提供 disabled
選項(xiàng)是建議的做法。
對(duì)于選擇框,如果是動(dòng)態(tài)選擇框的話,我們可以利用前面學(xué)習(xí)的v-for
指令來(lái)幫助我們:
<!-- Template --> <div id="app"> <select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <div>你選擇了: {{ selected }}</div> </div> // JavaScript let app = new Vue({ el: '#pp', data: { selected: '請(qǐng)選擇', options: [ { text: 'One', value: 'CSS' }, { text: 'Two', value: 'HTML' }, { text: 'Three', value: 'JavaScript' } ] } })
效果是什么樣呢?自己動(dòng)手寫(xiě)一下。這里我們用到了Vue的一個(gè)新指令,那就是v-bind
指令,他有什么功能或特性呢?咱們后續(xù)會(huì)學(xué)習(xí)。
上面向大家展示了v-model
指令在常見(jiàn)的表單控件上的使用情況。建議大家自己動(dòng)手?jǐn)]一下代碼,體會(huì)將會(huì)更深。
v-model
的修飾符
v-model
還有一些修飾符的功能,主要有.lazy
、number
和.trim
。其主要功能是:
.lazy
:默認(rèn)情況下,v-model
在input
事件中同步輸入框的值與數(shù)據(jù),但添加了.lazy
修飾符之后,從而轉(zhuǎn)變?yōu)樵?code>change事件中同步。簡(jiǎn)單點(diǎn)說(shuō)就是延遲了.number
:如果想自動(dòng)將用戶的輸入值轉(zhuǎn)換為Number
類(lèi)型(如果原值的轉(zhuǎn)換結(jié)果為NaN
則返回原值),可以添加.number
修飾符給v-model
來(lái)處理輸入值.trim
:如果要自動(dòng)過(guò)濾用戶輸入的首尾空格,可以添加.trim
修飾符給v-model
上過(guò)濾輸入
路們來(lái)看一個(gè)示例:
<!-- Template --> <div id="app"> <ul> <li> <label>不帶任何修飾符:</label> <input type="text" v-model="message" placeholder="Hello W3cplus!(^_^)" /> <span>{{message}}</span> </li> <li> <label>帶.lazy修飾符:</label> <input type="text" v-model.lazy="message" placeholder="Hello W3cplus!(^_^)" /> <span>{{message}}</span> </li> <li> <label>帶.number修飾符:</label> <input type="text" v-model.number="message" placeholder="Hello W3cplus!(^_^)" /> <span>{{message}}</span> </li> <li> <label>帶.trim修飾符:</label> <input type="text" v-model.trim="message" placeholder="Hello W3cplus!(^_^)" /> <span>{{message}}</span> </li> </ul> </div> // JavaScript var app = new Vue({ el: '#app', data: { message: 'Hello W3cplus!(^_^)', } })
刷新頁(yè)面看效果:
從上在的效果可以看出:
- 不帶修飾符:修改
input
的值,message
立馬變同步input
的輸入值 - 帶
.lazy
修飾符: 修改input
的值,message
并不會(huì)立馬同步input
的輸入值,只有當(dāng)input
失去焦點(diǎn)時(shí),message
才會(huì)同步input
的輸入值 - 帶
.number
修飾符: 當(dāng)輸入框的值,以數(shù)字加其他字符組合的內(nèi)容,會(huì)自動(dòng)去除其他的字符,只留數(shù)字;如果是其他字符加數(shù)字組合的內(nèi)容,并不會(huì)刪除其他字符,只留數(shù)字。一般帶.number
修飾符的input
控制配合type="number"
配合使用 - 帶
.trim
修飾符:input
輸入框開(kāi)始或末尾有空字符,將會(huì)自動(dòng)刪除空字符,如果空字符在其他字符中間,則不會(huì)刪除空字符
總結(jié)
這篇文章主要學(xué)習(xí)了Vue中的v-model
的簡(jiǎn)單功能,就是和表單控件實(shí)現(xiàn)雙向數(shù)據(jù)綁定。其實(shí)很多時(shí)候HTML內(nèi)建的input
類(lèi)型有時(shí)不能滿足我們的需求。這個(gè)時(shí)候有需要通過(guò)Vue的組件系統(tǒng)來(lái)創(chuàng)建自定義行為而且可復(fù)用的input
類(lèi)型。這些input
類(lèi)型甚至可以和v-model
一起使用。這就涉及到了Vue的組件。那么v-model
怎么和組件一起使用呢?我們后續(xù)將會(huì)學(xué)習(xí)這部分,因?yàn)閷W(xué)習(xí)這部分內(nèi)容,需要對(duì)組件有一定的了解。
原文地址:https://www.w3cplus.com/vue/v-model.html
(學(xué)習(xí)視頻分享:web前端開(kāi)發(fā)、編程基礎(chǔ)視頻)