對於表單元素,Vue.js 提供一個專用的指令,可以讓你將 View 及資料建立雙向綁定。當雙向資料綁定建立之後,使用者輸入的內容會自動儲存到一個變數中,同時,這個變數的資料會被更新到所有和它綁定的 View 中,看起來就像是立即的資料同步。
關於雙向綁定
在表單元素中,我們要偵聽使用者的輸入,同時做出必要的資料更新,也就是同時做兩件事,雖然這麼做很容易,例如以下範例:HTML<div id="vm">
<input @keyup="onInput" :value="txt">
{{ txt }}
</div>
<script>
new Vue({
el: '#vm',
data: {
txt: ''
},
methods: {
onInput: function (event) {
this.txt = event.target.value
}
}
})
</script>
當你在輸入框中輸入任何內容,都會在放開按鍵時觸發事件,於是修改的資料 txt
會立即反應在 {{ txt }}
區塊中。當你手動修改 txt
的值,它的更動也會立即呈現在 <input>
及 {{ txt }}
中。也就是說,View (這裡的
<input>
及 {{ txt }}
) 和資料 (這裡的 txt
) 做了綁定,於是資料改變,View 跟著變;同時,資料 (這裡的 txt
) 也和 View (這裡的 <input>
) 做了綁定(這裡透過事件的觸發),於是 View (這裡的 <input>
) 的內容改變,資料也就跟著變。這麼做其實太複雜了,你可以想像當網站功能變多時會是什麼情況。Vue.js 提供了一個更容易使用的指令
v-model
來做這件事,使用它,你就不用寫得像前面的範例一樣複雜,當網站的功能變多時,你的程式碼仍可以保持精簡,程式碼越少,就越不容易犯錯。看看用 v-model
的範例:
HTML<div id="vm">
<input v-model="txt">
{{ txt }}
</div>
<script>
new Vue({
el: '#vm',
data: {
txt: ''
}
})
</script>
v-model
實際上就是在做前一個範例中所做的事,當你瞭解它在做什麼,看起來就不會覺得太神奇了。
v-model
雙向資料綁定的指令有些限制,只能在表單元素或 Vue 元件上使用:<input>
<select>
<textarea>
- Vue Components
單行輸入框 (input)
在前面的範例中就已經說明如何使用,這裡就不重覆。多行輸入框 (textarea)
使用範例:HTML<div id="vm">
Content:
<pre>{{ content }}</pre>
<br>
<textarea v-model="content"></textarea>
</div>
<script>
var vm = new Vue({
el: '#vm',
data: {
content: ''
}
})
</script>
其實和 <input>
是一樣的。這裡要注意,在 <textarea>{{ content }}</textarea>
中使用雙括號 {{ }}
插入資料的方式是無效的,只能用 v-model
。複選按鈕 (checkbox)
使用範例:HTML<div id="vm">
<label>
<input type="checkbox" v-model="chkAnswer">{{ chkAnswer }}
</label>
</div>
<script>
var vm = new Vue({
el: '#vm',
data: {
chkAnswer: false
}
})
</script>
當你按一下複選按鈕,如果勾選的話,chkAnswer 就會變成 true ;反之則是 false。要在多個項目中複選,只要將
v-model
指定同一個名稱即可,這些按鈕就會視為同一群組:
HTML<div id="vm">
<label>
<input type="checkbox"
value="Miss Fortune"
v-model="chkCharacters">Miss Fortune
</label>
<br>
<label>
<input type="checkbox"
value="Akali"
v-model="chkCharacters">Akali
</label>
<br>
<label>
<input type="checkbox"
value="Caitlyn"
v-model="chkCharacters">Caitlyn
</label>
<hr>
選擇的角色:
<ul>
<li v-for="character in chkCharacters">{{ character }}</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#vm',
data: {
chkCharacters: []
}
})
</script>
輸出結果:
單選按鈕 (Radio)
Checkbox 是用來複選的;Radio 則是用來單選的。你可以將前面的複選範例中的
type="checkbox"
換成 type="radio"
就變成單選了,例如:
HTML<div id="vm">
<label>
<input type="radio"
value="Miss Fortune"
v-model="character">Miss Fortune
</label>
<br>
<label>
<input type="radio"
value="Akali"
v-model="character">Akali
</label>
<br>
<label>
<input type="radio"
value="Caitlyn"
v-model="character">Caitlyn
</label>
<hr>
選擇的角色:{{ character }}
</div>
<script>
var vm = new Vue({
el: '#vm',
data: {
character: ''
}
})
</script>
因為是單選,所以資料值就只是字串,而不是陣列。輸出結果:
下拉式選單 (select)
使用範例:HTML<div id="vm">
<select v-model="character">
<option>Miss Fortune</option>
<option>Akali</option>
<option value="Cait.">Caitlyn</option>
</select>
<br>
選擇的角色:{{ character }}
</div>
<script>
new Vue({
el: '#vm',
data: {
character: ''
}
})
</script>
在 <select>
元素上透過 v-model
雙向綁定 character
這個資料屬性,當其中一個 <option>
被選中時,它的內容或值 (value) 就會存入 character
資料屬性中。<option>
如果沒有指定 value
屬性,它包含的內容會被當成值。輸出結果:
如果要複選的話,要在
<select>
元素加上 multiple
屬性。同時,你的資料屬性現在是陣列了,而不是字串,所以我們修改它的名稱後面加上 s 來明確它的內容:
HTML<div id="vm">
<select v-model="characters" multiple>
<option>Miss Fortune</option>
<option>Akali</option>
<option>Caitlyn</option>
</select>
<br>
選擇的角色:
<ul>
<li v-for="c in characters">{{ c }}</li>
</ul>
</div>
<script>
new Vue({
el: '#vm',
data: {
characters: []
}
})
</script>
輸出結果:
很多時候,你的
<option>
是由資料動態建立的,這時候就要把之前學到的東西拿來用用看了。在
<select>
上用 v-model
綁定的資料是被選中的項目;透過 v-for
重覆執行要建立的 <option>
,同是用 v-bind:value (簡寫 :value)
來綁定 value
屬性,最後用雙括號 {{ }}
插入文字內容:
HTML<div id="vm">
<select v-model="character">
<option v-for="c in characters" :value="c.value">
{{ c.text }}
</option>
</select>
<br>
選擇的角色:{{ character }}
</div>
<script>
new Vue({
el: '#vm',
data: {
character: '',
characters: [
{text: 'Miss Fortune', value: 'MF'},
{text: 'Akali', value: 'Ak'},
{text: 'Caitlyn', value: 'CA'}
]
}
})
</script>
這裡的 characters
給選單用的資料是個陣列,每一個項目都是一個值物件,其中有兩個自定的屬性 text
及 value
。在實際應用上,這裡的資料通常會是從伺服器上下載下來後指定的。 假如你在瀏覽器(這裡用 Firefox)的主控台,輸入
vm.__vue__.characters.push({text:'Irelia', value:'IR'})
註:在 JSFiddle 中必須切換目標文件為 https://fiddle.jshell.net/_display/ 才能執行。這是模擬非同步的行為,當資料從伺服器下載完成,直接改變資料,頁面上的
<option>
項目就會立即改變,不需要重新整理頁面。修飾符號
.lazy
v-model
在 input
事件中,預設會同步輸入框的資料和值,也就是你輸入什麼字就立即反應。如果你加上 .lazy
,就會改成在 onchange
事件觸發時才同步,也就是輸入框失去焦點時:
HTML<input v-model.lazy="text">
直接在 v-model
後面接上 .lazy
就可以了。.number
如果你要將使用者的輸入轉為 Number 型態,可以加上.number
,如果輸入值可以轉成 Number 就將它轉換:
HTML<input v-model.number="age" type="number">
會有這個修飾符號的原因是,即使輸入框被註明為 type="number"
,它的回傳值依然是字串。.trim
很多時候你會用 Javascript 的 trim() 函式將字串值的前後空格去除,.trim
可以直接幫你做到:
HTML<input v-model.trim="text">
它不是即時同步,而是在 onchange
時才執行。
我要留言
留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。