在Day5 Vue指令-屬性綁定與列表渲染中有介紹到v-bind屬性綁定,它是一種單向的資料流綁定,而今天的內容將介紹資料的雙向綁定與修飾符。
當表單輸入的元素會更新到 Vue 實例資料,而 Vue 實例資料的變更會更新到輸入,使得兩者關係形成一種雙向的資料流綁定。
v-model 是語法糖,因為雙向綁定的功能其實可以透過v-bind和v-on來達到同樣的效果,v-bind:value從 Vue 實例資料更新輸入元素,而v-on:input從輸入更新 Vue 實例資料,不過使用v-model即可減少程式碼的撰寫,使得開發更方便,此外,雙向綁定經常和表單元素 <input>
、 <textarea>
以及 <select>
一起搭配使用。
<input v-model="message" /> 等同於
<input :value="message" @input="message = $event.target.value" />
以下將透過範例程式碼來介紹三種雙向綁定常用的應用:
透過在<input>
標籤中寫入v-model雙向綁定輸入的文字框與畫面呈現結果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div class="container">
<input type="text" v-model="InputText" placeholder="請輸入內容">
<p>輸入結果:</p>
<p v-bind="InputText.value">{{InputText}}</p>
</div>
<script>
Vue.createApp({
data(){
return{
InputText: ''
};
}
}).mount('.container');
</script>
</body>
</html>
以下畫面呈現結果可以看到輸入值會同步更新到畫面上
透過 <input>
標籤的類型可以呈現出單選框與複選框
我們先來看radio單選框的範例程式碼~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div class="container">
<h3>Are you a student ?</h3>
<div>
<input type="radio" id="one" value="Yes" v-model="picked">
<label for="one">Yes</label>
</div>
<div>
<input type="radio" id="two" value="No" v-model="picked">
<label for="Two">No</label>
</div>
<p>選擇結果:{{picked}}</p>
</div>
<script>
Vue.createApp({
data(){
return{
picked: ''
};
}
}).mount('.container');
</script>
</body>
</html>
接下來看checkbox複選框的範例程式碼~
需要特別注意在data內寫入的狀態是陣列[]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div class="container">
<h3>What kind of food do you like?</h3>
<div>
<input type="checkbox" id="Chinese food" value="Chinese food" v-model="checkedNames">
<label for="Chinese food">Chinese food</label>
</div>
<div>
<input type="checkbox" id="Western food" value="Western food" v-model="checkedNames">
<label for="Western food">Western food</label>
</div>
<div>
<input type="checkbox" id="Thai food" value="Thai food" v-model="checkedNames">
<label for="Thai food">Thai food</label>
</div>
<p>選擇結果:{{checkedNames}}</p>
</div>
<script>
Vue.createApp({
data(){
return{
checkedNames: []
};
}
}).mount('.container');
</script>
</body>
</html>
當checkbox選項只有一個時,可以以 true & false 切換勾選狀態
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div class="container">
<h3>I am a student.</h3>
<div>
<input type="checkbox" id="checkbox" v-model="isChecked">
<label for="checkbox">選擇結果:{{ isChecked }}</label>
</div>
</div>
<script>
Vue.createApp({
data(){
return{
isChecked: false
};
}
}).mount('.container');
</script>
</body>
</html>
透過<select >
和<option>
標籤一起搭配使用就可以呈現出下拉式列表選單
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div class="container">
<h3>請選擇你的職業</h3>
<select v-model="selected">
<option disabled value="">請選擇</option>
<option>工程師</option>
<option>設計師</option>
<option>作家</option>
</select>
<p>選擇結果:{{ selected }}</p>
</div>
<script>
Vue.createApp({
data(){
return{
selected: ''
};
}
}).mount('.container');
</script>
</body>
</html>
原本v-model雙向綁定<input>
的輸入值會即時同步更新到畫面,而加上.lazy修飾符後,則會當使用者離開輸入框 (例如:在輸入框按下enter鍵或是滑鼠點選輸入框外)時,輸入的資料才會更新到畫面上。
<input v-model.lazy="content">
由於v-model雙向綁定<input>
的輸入值都會被視為「字串」,在面對數字相加的情況下便無法順利計算,因此透過加上.number修飾符可以將輸入值轉換成「數字」類型,以便於執行數字的運算。
<input v-model.number="num1"> + <input v-model.number="num2"> = {{sum}}
為了防止使用者輸入無效的空格,透過加上.trim修飾符會去除輸入內容前後的空白。
<input v-model.trim="content">
https://www.w3schools.com/vue/vue_v-model.php
https://book.vue.tw/CH1/1-4-directive.html
https://medium.com/pierceshih/vue-js-%E5%AD%B8%E7%BF%92%E7%AD%86%E8%A8%98-day2-v-model%E8%B3%87%E6%96%99%E9%9B%99%E5%90%91%E7%B6%81%E5%AE%9A-9d54a82e23e5