Vue.js 學習旅程Mile 14 – Form Input Bindings 表單綁定篇:v-model


Posted by yuhantaiwan on 2020-06-07

基本用法

使用 v-model 可以對表單元素 <input><textarea><select> 進行資料的雙向綁定。
雙向綁定的意思是,data 驅動 view,也能從 view 改變 data
v-model 其實是一種語法糖 (syntax sugar),結合 v-bind (data binding) 與 v-on (event handling)。

v-model 針對不同的表單元素使用不同的屬性 property 與事件:

  • texttextarea 元素使用 value property 和 input 事件
  • checkboxradio 使用 checked property 和 change 事件;
  • select 元素將 value 作為 prop 並將 change 作為事件

注意

  • v-model 會忽略所有表單元素的 valuecheckedselected 這些屬性 attribute 的初始值。因此必須在一開始建立 Vue 實體時的 data 內宣告,才能達到響應式互動。

  • 中文、日文或是韓文的輸入法會需要將多個字組合後才會變為一個完整的字,例如中文的嗨就需要鍵入ㄏㄞˋ後按下 Enter 鍵才會輸入, v-model 並不會在拼音時就更新資料,而是會在按下 Enter 後才更新,因此如果想要讓資料在拼音時即時響應,可以直接使用 input 事件實作。

    • 補充:IME,input method editor 輸入法編輯器。可將輸入的按鍵轉換成其他語言的字元。例如常見的:注音輸入法編輯器、倉頡輸入法編輯器等。
<div>
  <button @click="msg=''">Clear</button>
  <input placeholder="Use IME" :value="msg" @input="msg=$event.target.value">
  {{msg}}
</div>

單行文字 <input type="text">

text 綁定的是字串

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

多行文字 <textarea>

textarea 綁定的是字串

<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

複選框 <input type="checkbox">

單一複選框

單一 checkbox 綁定的是布林值,判斷這個選項是否有勾選

<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

多個複選框

多個 checkbox 綁定的是陣列,當有勾選時,綁定的資料陣列會加上這個 input 標籤的 value 屬性值

<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>
<br>
<span>Checked names: {{ checkedNames }}</span>
new Vue({
  el: '...',
  data: {
    checkedNames: []
  }
})

單選按鈕 <input type="radio">

radio 綁定的是字串

<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>

選擇框 <select>

單選選擇框

單選 select 綁定的是字串

<div id="example-5">
  <select v-model="selected">
    <option disabled value="">請選擇</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
new Vue({
  el: '...',
  data: {
    selected: ''
  }
})

注意事項

如果初始值沒有符合任何的選項時, select 標籤會處於未選擇的狀態,也就是選項框中沒有任何值,在 IOS 下會有問題,因此最好的方法就是增加一個初始的選項,像是 <option disabled value="">Please select one</option> 來解決此問題。

複選選擇框

複選 select (加上 multiple 屬性) 綁定的是陣列

<select v-model="selected" multiple>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
v-for 渲染動態選項
<select v-model="selected">
  <option v-for="option in options" v-bind:value="option.value">
    {{ option.text }}
  </option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
  el: '...',
  data: {
    selected: 'A',
    options: [
      { text: 'One', value: 'A' },
      { text: 'Two', value: 'B' },
      { text: 'Three', value: 'C' }
    ]
  }
})

動態值綁定

value 動態綁定在 Vue 實體中的資料屬性上

複選框 <input type="checkbox">

checkbox 使用 true-valuefalse-value 分別綁定勾選及未勾選時的資料

<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no"
>
// when checked:
vm.toggle === 'yes'
// when unchecked:
vm.toggle === 'no'

注意

這裡的 true-valuefalse-value attribute 並不會影響輸入控件的 value attribute,因為瀏覽器在提交表單時不會包含未被選中的複選框。如果要確保表單中這兩個值中的一個能夠被提交,(即“yes”或“no”),請改用單選按鈕 radio

單選按鈕 <input type="radio">

<input type="radio" v-model="pick" v-bind:value="a">
// when checked:
vm.pick === vm.a

選擇框的選項 <select>

<select v-model="selected">
  <!-- inline object literal -->
  <option v-bind:value="{ number: 123 }">123</option>
</select>
// when selected:
typeof vm.selected // => 'object'
vm.selected.number // => 123

修飾符

.lazy

原本的 v-model 會在 input 事件觸發時更新資料,加上 .lazy 修飾符後,更新的時間點會被延到 change 事件時。因此如果加上 .lazy ,要在離開輸入框時才會更新資料

<!-- synced after "change" instead of "input" -->
<input v-model.lazy="msg">

.number

如果想讓輸入框的值其型別為數字,必須要使用 .number 修飾符

因為 HTML 的輸入框就算是 type="number" ,輸入值的型別也還是字串

<input v-model.number="age" type="number">

.trim

去除首尾空白

<input v-model.trim="msg">

參考資料


#w3HexSchool #Vue #javascript







Related Posts

Go語言字串

Go語言字串

Day 111

Day 111

JavaScript 的函式(Function)

JavaScript 的函式(Function)


Comments