Vue.js
對於表單元素,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.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。