iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
Modern Web

不用去柬埔寨也能活摘 Vue系列 第 14

[Vue] Day14 資料綁定:v-bind、v-model

  • 分享至 

  • xImage
  •  

上一篇的實作有跟各位提到 v-model,而這些在 Vue 中以 v- 為開頭的的屬性,都被稱之為「指令」。而當指令搭配運算式時,計算出的值被改變的話,所對應的標籤、節點、元件等也皆會被影響,也就是說,我們就可以透過指令的作用與狀態的變化去操控網頁系統。

資料綁定

在一開始我們在創建 Vue instance 與 Components時,通常會將兩者分別放到 Data,之後再到 body 裡使用 HTML 的語法去接收我們所撰寫的 Data,再讓使用者到網頁中輸入資訊,就能達到資料雙向綁定的目的了。

在我們之前的文章中,有跟各位提到 Vue 可以利用兩個大括弧 {{}} 去將資料輸出到網頁上。講到這裡就一定會有人問說,那網頁標籤內的「屬性」是不是也能這樣做呢?

讓我們看看以下的程式碼:

<template>
  <div>
    <p id="{{iThome_2022}}"></p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      iThome_2022: "example",
    };
  },
};
</script>

可以看到,我們先在 data 中宣告一個變數及給予他一個值,接著套用到模板上,照理來說我們的網頁就會出現 example的字樣對吧:

欸?畫面怎麼是一片空白?!是沒有開啟服務嗎?還是連錯網頁了?

<template>
  <div>
    <p id="{{iThome_2022}}"></p>
  </div>
  <div>
    <p>{{ iThome_2022 }}</p>  //對照組
  </div>
</template>

來!為了解決大家的疑問,我們在 html 上新增一行對照組 <p>{{ iThome_2022 }}</p>

再次看看我們的網頁:

偌大的網頁上只有一個孤苦伶仃的 example,而使用 {{}} 一樣沒有任何字樣。
/images/emoticon/emoticon02.gif
因此!我們可以得出解答了,html 的 {{}} 模板語法是無法被套用在標籤的屬性上的。
那以下,我們就來看看這些可以讓資料綁定的「屬性」吧!


v-bind (屬性綁定)

首先,要跟各位介紹的就是 v-bind 屬性綁定,能讓 Vue 去控制標籤的屬性,指令的用法不難,我們只需要在標上加上 v-bind:屬性名稱,舉個例子:

假如我們想控制 button 是否為可點擊時,就可以使用 v-bind:

<template>
  <div>
    <button v-bind:disabled="btnDisable">iThoneBtn</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      btnDisable: true
    };
  },
};
</script>

首先我們可以在 data 中宣告一個名為 btnDisable 的布林值,並將他的設定成 true,接著在 html 中放置一個 button 並新增 v-bind 的屬性。可以看到上方的程式碼,我們將此 button 的 disabled 狀態導向為 btnDisable,也就是 true,讓此 button 的狀態設為 無法點擊,此時網頁所呈現的:

那如果我們將 btnDisable 的屬性改成 false 時:

button 就可以點擊了!

而常見的標籤屬性如 id、src (圖片)、href (超連接) 等 DOM 屬性,都可以透過 v-bind 控制

寫法除了可以用 v-bind:屬性名稱 外,也能直接簡寫成 :屬性名稱,例如:

<button v-bind:disabled="btnDisable"> iThoneBtn </button>

改寫成:

<button :disabled="btnDisable"> iThoneBtn </button>

v-model (表單綁定)

想要一個互動性高的網頁,表單類型的元素是不可或缺的,而如果想在 Vue 中進行資料的雙向綁定,就需要透過 v-model 來實現,例如我們常見的表單元素:<input><textearea><select>

input

首先,我們先來介紹最常見的文字輸入框 input,將他綁定 input 事件:

<template>
  <div>
    <input v-model="iThome">
    <p> {{ iThome }} </p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      iThome: 'example'
    };
  },
};
</script>

由上方程式碼為例,首先我們先在網頁上放置一個 input,並且加上 v-model 讓他可以與下方的文字段落做資料雙向綁定,在初始時,我們將文字預設為 example

接著,在我們更改輸入框的文字時,下方的文字段落也會同步做修改:

textarea

那我們第二個要介紹的是文字方塊 textarea,使用方式與 input相同:

<template>
  <div>
    <textarea v-model="iThome"></textarea>
    <p> {{ iThome }} </p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      iThome: 'example'
    };
  },
};
</script>

來看看網頁:

要特別注意的是,若在 <textarea> 使用大括弧 {{}} 的模板語法時,會改變其內容,但資料也因為沒有回傳至 data 中,造成無法雙向綁定。只有利用 v-model 的指令才能與 data 中的狀態互相綁定,同時也能更新我們的文字段落,讓我們來看看兩者的差異:

<template>
  <div>
    <textarea>{{iThome}}</textarea>
    <br>
    <textarea v-model="iThome"></textarea>
    <p>{{ iThome }}</p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      iThome: "example",
    };
  },
};
</script>

我們放上兩個文字方塊,一個使用模板語法 {{}} 去呈現文字,另一個用 v-model 做資料雙向連接。從以下的網頁畫面可以得出如沒有 v-model,那文字段落就無法與文字方塊同步更改資料:

radio

相信大家都知道我們可以透過更改 input 的 type 讓他變成各種樣式,所以接下來要介紹的就是單選框:radio,我們只需要在 input 的標籤中加上 v-model,並且透過 vaule 去指定他的值即可:

<template>
  <div>
    <input type="radio" v-model="iThome_radio" value="1" id="example_1" />
    <label for="example_1">example_1</label>
  </div>
  <div>
    <input type="radio" v-model="iThome_radio" value="2" id="example_2" />
    <label for="example_2">example_2</label>
  </div>
  <p>{{ iThome_radio }}</p>
</template>
<script>
export default {
  data() {
    return {
      iThome_radio: 1,
    };
  },
};
</script>

首先,我們放上兩個 input,並將 type 指定為 radio,且分別將兩個 radio 的 vaule 的值設為 1 和 2,id 則是需要與各自 labelfor 值設為相同,才能相互連接。接著設定 v-model,最後將 data 中的 v-model 預設指定 1,讓我們第一個 radio 可以在初始時會被單選中,html 的部分就完成了。

checkbox

介紹完單選,接下來就是複選框拉,我們除了可以將 checkbox 當成複選框以外,當他只有一個時,又可以將它設為 true 或 false,接下來就來分別介紹吧。

  • 當 checkbox 為複選框時:
    用法與 radio 相同,但也因為複選的緣故,我們需要將 data 設為 陣列 []
<template>
  <div>
    <input type="checkbox" v-model="iThome_checkbox" id="example_1" value="1"/>
    <label for="example_1">example_1</label>
  </div>
    <div>
    <input type="checkbox" v-model="iThome_checkbox" id="example_2" value="2"/>
    <label for="example_2">example_2</label>
  </div>
    <div>
    <input type="checkbox" v-model="iThome_checkbox" id="example_3" value="3"/>
    <label for="example_3">example_3</label>
  </div>
    <div>
    <input type="checkbox" v-model="iThome_checkbox" id="example_4" value="4"/>
    <label for="example_4">example_4</label>
  </div>
    <div>
    <input type="checkbox" v-model="iThome_checkbox" id="example_5" value="5"/>
    <label for="example_5">example_5</label>
  </div>
  <p>{{ iThome_checkbox }}</p>
</template>
<script>
export default {
  data() {
    return {
      iThome_checkbox: []
    };
  },
};
</script>

來看看網頁所呈現的:

  • 當 checkbox 只有一個時:
    這時候只需要把 data 的屬性改成布林值,true 或 false 即可:
<template>
  <div>
    <input type="checkbox" v-model="iThome_checkbox" id="example" value="example"/>
    <label for="example">example</label>
  </div>
  <p>{{ iThome_checkbox }}</p>
</template>
<script>
export default {
  data() {
    return {
      iThome_checkbox: true
    };
  },
};
</script>

來看看網頁所呈現的:

select

接下來要介紹的也是常見標籤:下拉是選單 select,通常會與 option 搭配:

<template>
  <div>
    <select v-model="iThome_select" id="select">
      <option for="select" selected="selected">example_1</option>
      <option for="select">example_2</option>
      <option for="select">example_3</option>
    </select>
  </div>
  <p>{{ iThome_select }}</p>
</template>
<script>
export default {
  data() {
    return {
      iThome_select: "此為 iThome 範例",
    };
  },
};
</script>

要注意的是,我們的 v-model 必須放在 <select> 的標籤內,而不是 <option> 的標籤

以上就是我們對於常見的表單元素透過 v-model 進行資料雙向綁定的說明了。
接下來我們就接著看看 v-model 中修飾子的用法吧!


看完上方這些 v-model 與表單元素後,大家可以發現我們的資料在做更改時,也會同步觸發下方的文字段落,那就會有人問了,假如我不想讓他同時更新呢?

剛好這裡有一個可以滿足此需求的辦法,Vue.js 非常貼心的提供了一款「修飾子」的功能讓我們可以做出更好的網頁互動。而修飾子的用法通常是以 .XXX 的形式去附加到指令後方,而與 v-model 搭配的有以下三種:

  • .lazy
  • .number
  • .trim

接下來我們就來分別說明他們吧:


.lazy

我們可以在 v-model 的後方加上一個 .lazy,他可以幫助我們將 input 輸入框從原本單純的 input 事件更改為 change 監聽事件,讓我們能在使用者離開輸入框後,才會更新 data 中的資料內容:

<input v-model.lazy="iThome">

.number

當我們想讓輸入的資料做運算時,可以透過 v-model 的方式做同步更新,並配合 computed 做計算:

<template>
  <input v-model="iThome_num1" /> + <input v-model="iThome_num2" /> =
  {{ iThome_sum }}
</template>
<script>
export default {
  data() {
    return {
      iThome_num1: "",
      iThome_num2: "",
    };
  },
  computed: {
    iThome_sum() {
      return this.iThome_num1 + this.iThome_num2;
    },
  },
};
</script>


奇怪?為什麼等號後面的數值沒有做運算呢,而是將我剛才輸入的數字結合而已,相信各位一定有這個疑問,這時候我們只需要在 v-model 的後方加上 number,就可以讓 data 的屬性自動轉為數值:

<input v-model.number="iThome_num1" /> + <input v-model.number="iThome_num2" /> ={{ iThome_sum }}

就像這樣,再來看看我們的網頁:

這樣就成功了,因為我們在 v-model 後加上 .number 的修飾子,因次在更新狀態時,會先將對應的資料先轉換成數字的格式,接著再至 computed 中做運算,所回傳的就是運算結果了。

.trim

當我們讓 v-model 在我們輸入資料時,去過濾前後的空白字元,就可以使用 .trim

<template>
  <input v-model.trim="iThome_trim" />
  <p>{{iThome_trim}}</p>
</template>
<script>
export default {
  data() {
    return {
      iThome_trim: "",
    };
  },
};
</script>

最後來看看網頁的表現:

/images/emoticon/emoticon07.gif

好拉!那以上就是我們對於 v-bind 與 v-model 事件與修飾子的介紹了
明天就會進入到模板綁定教學,我們就明天見 ~


上一篇
[Vue] Day13 methods及computed 的資料整合與邏輯運算
下一篇
[Vue] Day15 模板綁定:v-text、v-html、v-once、v-pre
系列文
不用去柬埔寨也能活摘 Vue30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言