---
# System prepended metadata

title: v-model(資料雙向綁定)

---

# v-model(資料雙向綁定)

## input
ex: 當 v-model 與不同類型搭配時，所產生的資料格式也不太相同。

```
##<h3>input</h3>

  <input type="text" class="form-control" v-model="name">
  {{ name }}
  
  <!--  input 直接綁定 v-model="name" 時， 可以直接對應到 data 的值 ， 所以當 input
  做變更時，資料就會直接雙向綁定(同時做更動)；如下圖-->
```
![](https://i.imgur.com/Vd0jfoD.jpg)

```
<script>
const App = {
  data() {
    return {
      name: '小明',
    }
  },
};

Vue.createApp(App)
  .component('list-item', {
    template: `
      <li>
        {{ item.name}} / {{ item.price }} 元
      </li>
    `,
    props: ['item']
  }).mount('#app');
</script>
```
---------------------------------------------------------------------------

## textarea
```
##<h3>textarea</h3>
  <textarea cols="30" rows="3" class="form-control" v-model="text">    
  </textarea>
  {{ text }}
  
  <!-- 同 input 一樣   -->
```
![](https://i.imgur.com/TmU4zRB.jpg)
```
<script>
const App = {
  data() {
    return {
      text: '一段文字敘述',
    }
  },
};

Vue.createApp(App)
  .component('list-item', {
    template: `
      <li>
        {{ item.name}} / {{ item.price }} 元
      </li>
    `,
    props: ['item']
  }).mount('#app');
</script>
```
---------------------------------------------------------------------------

## checkbox 單選框
    
```
##<h3>checkbox 單選框</h3>
  <p>小明，你是吃飽沒？</p>
  <p>{{ checkAnswer ? '吃飽了' : '還沒'}}</p> // 三元運算子: checkAnswer ?(是否成立)  '吃飽了(true)':'還沒(false)')
  <p>{{ checkAnswer}}</p>
  
  <div class="form-check">
    <input type="checkbox" v-model="checkAnswer" class="form-check-input" id="check1" >
    <!-- 若是綁定到單一一個 <input type="checkbox" >的話，會以布林值的方式作呈現(true || false) ； 所以當 v-model=" " 代入 checkAnswer 時，會是 (true || false) 的結果，在利用 input 本身 有 onchange event 特性，做 (true || false) 切換-->
  
    <label class="form-check-label" for="check1">小明回覆</label>
  </div>
  
```
ps.當為 true 時，則是 `<input type="checkbox" >` 為 打勾 狀態:如下圖
![](https://i.imgur.com/gSdk8dL.jpg)
   反之
![](https://i.imgur.com/EWsln9X.jpg)

---
```
##<h3>checkbox 單選延伸</h3>
  <p>小明，你是吃飽沒？</p>
  <p>{{ checkAnswer2 }}</p>
  <div class="form-check">
  
    <input type="checkbox" v-model="checkAnswer2" true-value="吃飽了" false-value="還沒" class="form-check-input" id="check2" >
    <!-- 也可以利用 true-value="吃飽了" 以及 false-value="還沒" 的方式，將文字進行單選的切換 ； 同樣可以獲得一樣的效果   -->
    
    <label class="form-check-label" for="check2">小明回覆</label>
  </div>  
```
ps. data()內的 checkAnswer2 須先預設為空字串 ； 如右: checkAnswer2: ''

```
<script>
const App = {
  data() {
    return {
      checkAnswer: false,
      checkAnswer2: '',
    }
  },
};

Vue.createApp(App)
  .component('list-item', {
    template: `
      <li>
        {{ item.name}} / {{ item.price }} 元
      </li>
    `,
    props: ['item']
  }).mount('#app');
</script>
```
---------------------------------------------------------------------------

## checkbox 複選框
ex: 當 checkbox 遇到複選時??
```
##<h3>checkbox 複選框</h3>
  <p>你還要吃什麼？</p>
  <p>{{ checkAnswer3.join('、') }}</p> 
  <div class="form-check">
    <input type="checkbox" v-model="checkAnswer3" class="form-check-input" id="check3" **value="蛋"** >
    <label class="form-check-label" for="check3">蛋餅</label>
  </div>
  <div class="form-check">
    <input type="checkbox" v-model="checkAnswer3" class="form-check-input" id="check4" **value="蘿蔔"** >
    <label class="form-check-label" for="check4">蘿蔔糕</label>
  </div>
  <div class="form-check">
    <input type="checkbox" v-model="checkAnswer3" class="form-check-input" id="check5" **value="漿"** >
    <label class="form-check-label" for="check5">豆漿</label>
  </div>
  
※ 在複選上是對應 value=" " 這個裡面的值，所以可將 v-model=" " 綁定的資料格式設為空陣列，如右: checkAnswer3: []。 ； 
所以當勾選 <input type="checkbox"> 這個選項時，裡面的值就會被代入到 checkAnswer3: [] 這個空陣列內；反之當取消勾選時，也會自動移除(如下圖)
```
![](https://i.imgur.com/Y2mHKoj.jpg)

```
<script> 
const App = {
  data() {
    return {
      checkAnswer3: [],    
    }
  },
};

Vue.createApp(App)
  .component('list-item', {
    template: `
      <li>
        {{ item.name}} / {{ item.price }} 元
      </li>
    `,
    props: ['item']
  }).mount('#app');
</script>
```
---
## radio 單選框
```
##<h3>radio 單選框</h3>
  <p>你還要吃什麼？</p>
  <p>{{ radioAnswer }}</p>
  <div class="form-check">
    <input type="radio" v-model="radioAnswer" class="form-check-input" id="radio1" value="餅" >
    <label class="form-check-label" for="radio1">蛋餅</label>
  </div>
  <div class="form-check">
    <input type="radio" v-model="radioAnswer"  class="form-check-input" id="radio2" value="糕" >
    <label class="form-check-label" for="radio2">蘿蔔糕</label>
  </div>
  <div class="form-check">
    <input type="radio" v-model="radioAnswer"  class="form-check-input" id="radio3" value="豆" >
    <label class="form-check-label" for="radio3">豆漿</label>
  </div>
```

PS. radio 跟 checkbox 不同的地方在於， radio 是屬於單選框，而 checkbox 是屬於複選框；
當 radio 出現時，data() 定義的資料為單一個值。

假設我在資料結構內先預設 radioAnswer: '蛋餅'時，他在畫面上的預設值就是 蛋餅 :如下圖
![](https://i.imgur.com/O7tBi8R.jpg)

當我選擇其他選項時，他不是以陣列的方式加入到這個欄位裡  `<p>{{ radioAnswer }}</p>` ； 而是用
複寫的方式將原有的資料欄位覆寫過去:如下圖
![](https://i.imgur.com/7uyOqj4.jpg)

```
<script> 
const App = {
  data() {
    return {
      radioAnswer: '蛋餅',   
    }
  },
};

Vue.createApp(App)
  .component('list-item', {
    template: `
      <li>
        {{ item.name}} / {{ item.price }} 元
      </li>
    `,
    props: ['item']
  }).mount('#app');
</script>
```
---
## select 單選
```
##<h3>select 單選</h3>
  <p>你還要吃什麼？</p>
  <p>{{ selectAnswer }}</p>
  
  <select class="form-select" v-model="selectAnswer">
  <!-- 將 v-model 綁定到  select 資料欄位上  -->
  
    <option value="" disabled>說吧，你要吃什麼？</option>
    <option :value="it.name" v-for="it in products" :key="it.name" >{{it.name}}/{{it.price}}</option>
    <!--  select 的資料欄位是在 option 標籤 value=" " 裡，所以當 select 在做選擇時，
    他其實是把 option 標籤裡的 value="值" ， 加入到 data()資料的 selectAnswer:' ' 裡面，
    並將其值代出-->
  </select>
```
PS.可將 option 標籤使用 v-for="it in products"，代出 products 裡面的資料並賦予到 it 參數上，作為 option 的選項；如下圖

![](https://i.imgur.com/7x3QFYc.png)

   必須特別注意一點的是，只要有使用 v-for 就要加上 :key= "  "的值(綁定的 key 必須是唯一值)，之後在定義一個 value 的值，將其綁定後；畫面上渲染的部分就會呈現 name 屬性名稱的值: 如下圖

![](https://i.imgur.com/KXzwcMx.jpg)




為什麼使用 v-for 時，需要綁定 key 值呢?

** 因為在用 v-for 迴圈常會搭配 key 綁值， key 的用途就是用來辨識 virtual DOM 的更新情況，其中 virtual DOM 的特性之一就是會重複使用原本的組件，要更新時不會整個組件的 DOM 元素砍掉然後再全部渲染一次，而是只更新部分資料，這樣做可以提升效能。
**


```
<script>
const App = {
  data() {
    return {
      selectAnswer: '',
      products: [
        {
          name: '蛋餅',
          price: 30,
          vegan: false
        },
        {
          name: '飯糰',
          price: 35,
          vegan: false
        },
        {
          name: '小籠包',
          price: 60,
          vegan: false
        },
        {
          name: '蘿蔔糕',
          price: 30,
          vegan: true
        },
      ],
    }
  },
  methods: {
    reverseArray: function () {
      this.products.reverse();
    },
  },
};

Vue.createApp(App)
  .component('list-item', {
    template: `
      <li>
        {{ item.name}} / {{ item.price }} 元
      </li>
    `,
    props: ['item']
  }).mount('#app');
</script>
```
---

## select 多選

```
<h3>select 多選</h3>
  <p>你還要吃什麼？</p>
  <p>{{ selectAnswer2 }}</p>
  
  <select class="form-select" v-model="selectAnswer2" multiple>
  <!-- 將data()資料的 selectAnswer2:'[ ]' 設為一個空陣列，並將其綁定在 select 的資料欄位上
  v-model="selectAnswer2" ； 若要將 select 改為多選的情況下，只須將欄位內添加 **multiple** 
  之後就會變成多選的選項，那他的資料結果就是一個陣列形式-->
  
    <option selected disabled value="">說吧，你要吃什麼？</option>
    <option :value="item.name" v-for="item in products" :key="item.name">
    {{item.name}} / {{item.price}} 元</option>
  </select>
```
![](https://i.imgur.com/5UeaNjI.jpg)


```
<script>
const App = {
  data() {
    return {
      selectAnswer2: [],
      products: [
        {
          name: '蛋餅',
          price: 30,
          vegan: false
        },
        {
          name: '飯糰',
          price: 35,
          vegan: false
        },
        {
          name: '小籠包',
          price: 60,
          vegan: false
        },
        {
          name: '蘿蔔糕',
          price: 30,
          vegan: true
        },
      ],
    }
  },
  methods: {
    reverseArray: function () {
      this.products.reverse();
    },
  },
};

Vue.createApp(App)
  .component('list-item', {
    template: `
      <li>
        {{ item.name}} / {{ item.price }} 元
      </li>
    `,
    props: ['item']
  }).mount('#app');
</script>
```
---

# v-model修飾符

修飾符是在 v-model 的後方增加一個 點 再加上特定的字串；如右 : v-model.xxx = "　"

第一個: v-model.lazy = " "

其用途: 當輸入文字時，資料庫不會馬上綁定(同步)，需 點擊 外部區域或按壓 enter 後，判斷已完成輸入框事件時，才會作動

第二個: v-model.number = " "

其用途: 確保輸入內容為存數值型別時，可以加上在 v-model 後方加上 number ；就可以確實轉為數值型別，但需要確定 `<input 的 type="number">`，他的運作才會比較正常。

第三個: v-model.trim = " "

其用途: 將資料內容的前後空白字元自動刪除