[Vue] Vue指令-雙向綁定
TL;DR
使用v-model會根據所定義的資料格式不同,以及所綁定的input不同有不一樣的效果。
相關連結
- 表單輸入綁定 | Official
input
最基本的使用方式,輸入什麼,資料內的字串就會跟著變化
input(text)
- html(#app)
- vue
<h3>input:text</h3>
<input type="text" class="form-control" v-model="name">
{{ name }}
const App = {
data() {
return {
name: "小明",
num: "5",
text: "一段文字敘述",
......
};
},
methods: {}
};
Vue.createApp(App).mount("#app");
input(number)
- html(#app)
- vue
<h3>input:number</h3>
<input type="number" class="form-control" v-model="num">
{{ num }}
const App = {
data() {
return {
name: "小明",
num: "5",
text: "一段文字敘述",
......
};
},
methods: {}
};
Vue.createApp(App).mount("#app");
textarea
- html(#app)
- vue
<h3>textarea</h3>
<textarea cols="30" rows="3" class="form-control" v-model="text"></textarea>
{{ text }}
const App = {
data() {
return {
name: "小明",
num: "5",
text: "一段文字敘述",
......
};
},
methods: {}
};
Vue.createApp(App).mount("#app");
checkbox
單選
單選的時候我們的資料格式會設定成布林值。選取會對應true
,不選取對應false
。
另外可以使用三元運算子調整渲染的文字內容,也可以在資料內給予初始預設值。
- html(#app)
- vue
<h3>checkbox 單選框</h3>
<p>小明,你是吃飽沒?</p>
<p>{{ checkAnswer}}</p>
<p>{{ checkAnswer ? '吃飽了' : '還沒'}}</p>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="check1" v-model="checkAnswer">
<label class="form-check-label" for="check1">小明回覆</label>
</div>
const App = {
data() {
return {
// 可以給予預設值ture,會預設選取
checkAnswer: true,
checkAnswer2: "小明還沒回覆",
checkAnswer3: [],
......
};
},
methods: {}
};
Vue.createApp(App).mount("#app");
前面使用三元運算子,可以將ture
跟false
的值分別對應渲染出 "吃飽了" 跟 "還沒"
還有另一種設定方式,可以達到一樣的效果:
const App = {
data() {
return {
checkAnswer: true,
checkAnswer2: "小明還沒回覆",
checkAnswer3: [],
};
},
methods: {}
};
Vue.createApp(App).mount("#app");
<p>小明,你是吃飽沒?</p>
<p>{{ checkAnswer2 }}</p>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="check2"
v-model="checkAnswer2"
true-value="吃飽了"
false-value="還沒吃飽"
>
<label class="form-check-label" for="check2">小明回覆</label>
</div>
預設會顯示資料內的 “小明還沒回覆”,等到我們點選了按鈕,變成true的時候,就會改為顯示 吃飽了 ,再點一次變成false的時候會顯示 還沒吃飽 。
複選
要使用複選的checkbox的時候,v-model所綁定的資料需要是一個陣列。會分別將checked
的按鈕對應的value
給push到綁定的資料陣列中。
需要注意,這邊所傳入陣列的資料是value的值。
我們可以在資料的陣列內,直接加入希望預設勾選的checkbox
的value
。則對應的選項就會被預設勾選。
如我們直接設定checkAnswer3:["蘿蔔糕","豆漿"]
,則蘿蔔糕跟豆漿都會被預設勾選。
但是如果今天在input
內設定為vale="蘿蔔糕3"
,則會因為找不到對應value
的checkbox
,所以並不會如我們設想的預設勾選。
- html(#app)
- vue
<h3>checkbox 複選框</h3>
<p>你還要吃什麼?</p>
<p>{{ checkAnswer3.join(' ') }}</p>
<p>{{ checkAnswer3 }}</p>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="check3" value="蛋餅" v-model="checkAnswer3">
<label class="form-check-label" for="check3">蛋餅</label>
</div>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="check4" value="蘿蔔糕" v-model="checkAnswer3">
<label class="form-check-label" for="check4">蘿蔔糕</label>
</div>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="check5" value="豆漿" v-model="checkAnswer3">
<label class="form-check-label" for="check5">豆漿</label>
</div>
const App = {
data() {
return {
checkAnswer: true,
checkAnswer2: "小明還沒回覆",
checkAnswer3: [],
......
};
},
methods: {}
};
Vue.createApp(App).mount("#app");
radio
沒有使用框架的時候,如果我們想要組成一個 radio group ,則需要在每個radio上加上name
屬性。
使用vue的時候,會根據我們在v-model
所綁定的資料,框架會自動幫我們調整好變成一個群組。我們就可以專心在資料上的處理。
使用時需要將資料設定為字串,如果字串值有對應到radio的value,則該radio會為預設選取。
select
單選
有時候我們會希望在一開始顯示一個預設的提示選項(例如:說吧,你要吃什麼)。但是當使用者選擇完畢之後又不希望使用者可以選擇回預設提示選項,這時候就可以善用disabled功能來達成。
首先先在預設的選項上撰寫一個value,並且讓data內的值與這個value相同(可以為空字串)。這麼一來,就會預設顯示該選項。
另外,我們可以在這個選項上加上disabled,這樣一來當使用者點選其他選項後,就會因為這個disabled而無法選擇回我們的提示選項。
- html(#app)
- vue
<h3>select 單選</h3>
<p>你還要吃什麼?</p>
<p>{{ selectAnswer }}</p>
<select class="form-select" v-model="selectAnswer">
<option :value="" disabled>說吧,你要吃什麼?</option>
<option v-for="item in products" :key="item.name" :value="item.name">{{item.name}} / {{item.price}} 元</option>
</select>
const App = {
data() {
return {
selectAnswer: "",
selectAnswer2: ["蛋餅", "小籠包"],
products: [
{
name: "蛋餅",
price: 30,
vegan: false
},
{
name: "飯糰",
price: 35,
vegan: false
},
{
name: "小籠包",
price: 60,
vegan: false
},
{
name: "蘿蔔糕",
price: 30,
vegan: true
}
],
productsObj: {
chineseOmelette: {
name: "蛋餅",
price: 30,
vegan: false
},
riceBall: {
name: "飯糰",
price: 35,
vegan: false
},
soupDumpling: {
name: "小籠包",
price: 60,
vegan: false
},
radishCake: {
name: "蘿蔔糕",
price: 30,
vegan: true
}
}
};
}
methods: {}
};
Vue.createApp(App).mount("#app");