最後一篇 Vue 的基礎,會提到修飾符、還有 v-bind 切換 class,表單的運用,還有 component 的概念。
修飾符
修飾符在網頁中很常使用到,例如點擊一個 a 連結,不想讓他產生作用的話,就會使用到 preventDefault()
這個語法,例如 jQuery 的用法:
1 2 3 4 5 6 7
| <a href="http://www.google.com">Click me</a> <script> $("a").on("click", function(e) { e.preventDefault(); }); </script>
|
這樣子點擊的話,連結就不會有作用。
而在 Vue 中也有這個用法,阻止默認行為:
<button @click.prevent="doThis"></button>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <div id="app"> <input type="text" v-model="text"> <!-- 當點擊a連結,一樣可以執行function,但不會連到Google --> <a href="http://www.google.com" @click.prevent="reverseText">Reverse Text</a> <div class="showText"> {{newText}} </div> </div> <script> var app = new Vue({ el: "#app", data: { text: "", newText: "" }, methods: { reverseText: function() { this.newText = this.text.split("").reverse().join(""); } } }); </script>
|
透過 v-bind:class 來綁定 HTML
可以給予 v-bind:class
一個 class 對象,去做出動態切換 class
<div v-bind:class="{ class名稱: 切換的動作 }"></div>
看以下範例,有一個藍色的方塊,只要在 class 名稱加上 yellow,就會變成黃色:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <div id="app"> <!-- 只要在class動態加上yellow就會變黃色 --> <div class="box"></div> <button class="changeColor btn btn-primary">Change Color</button> </div> <style> .box { width: 250px; height: 250px; background-color: blue; } .box.yellow { background-color: yellow; } </style> <script> var app = new Vue({ el: "#app", data: { change: false // 這邊有一個切換動作change的data } }); </script>
|
1 2 3 4 5 6
| <div id="app"> <!-- 加上 v-bind:class="{class名稱: 切換的動作}" --> <div class="box" :class="{'yellow': change}"></div> <!-- 在按鈕綁定click,讓它去做切換的效果 --> <button class="changeColor btn btn-primary" @click="change = !change">Change Color</button> </div>
|
計算屬性 computed 的使用
下面的範例是當在 text
欄位輸入文字時,會在 .showText
顯示反轉文字
不過
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <div id="app"> <h2>直接輸入文字</h2> <input type="text" class="form-control mt-3" v-model="text"> <h2>在下方顯示反轉文字</h2> <h3 class="showText"> {{text.split("").reverse().join("")}} </h3> </div> <script> var app = new Vue({ el: "#app", data: { text: "" } </script>
|
但是如果要重複使用 {{text.split("").reverse().join("")}}
這一段的話,會有點難維護,所以可以運用 computed 來處理
1 2 3 4 5 6 7 8 9 10 11
| var app = new Vue({ el: "#app", data: { text: "" }, computed: { reverseText: function() { // 在 computed 中要使用 function return this.text.split("").reverse().join(""); // 並且會回傳值,所以就可以應用在回傳反轉後的結果 } } });
|
接著只要加上回傳值的 function,就可以顯示結果了。
1 2 3 4 5 6 7 8
| <div id="app"> <h2>直接輸入文字</h2> <input type="text" class="form-control mt-3" v-model="text"> <h2>在下方顯示反轉文字</h2> <h3 class="showText"> {{reverseText}} </h3> </div>
|
那麼 computed 跟 methods 在使用上有什麼差異呢?
- computed 一般用來回傳用於畫面呈現的資料 在監控資料更動後,重新運算後將結果呈現於畫面上。由於資料變動就會觸發,所以如果運行的資料太多,在效能處理上就會變慢。
- methods 是運用在互動的函式,可以用來修改資料,內容因為需要觸發才會運作,所以如果資料量大的話會建議使用 methods。
Vue 表單與資料的綁定
前面有提到 Vue 雙向綁定用 v-model
的用法,這個部份來看看其他綁定的用法。
checkbox
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div id="app"> <div class="form"> <label for="dinner">要吃晚餐嗎?</label> <input type="checkbox" v-model="checkboxDinner" id="dinner"> {{checkboxDinner}} </div> </div>
<script> var app = new Vue ({ el: "#app", data: { checkboxDinner: false, // checkbox 選項只有true或false } }) </script>
|
checkbox
的用法這邊用在是或不是的選項 ,這邊預設是 false,當點擊時就會變成 true。
還有加入 Array 的用法:
1 2 3 4 5 6
| var app = new Vue ({ el: "#app", data: { checkboxArray: [], } })
|
這裏有綁定 3 個選項,當點擊 checkbox
,data 的 checkboxArray 空陣列就會填入該選項的 value,最後會顯示在 <span>
中的 v-for
迴圈。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div id="app"> <div class="form"> <div class="form-check"> <input type="checkbox" class="form-check-input" id="check2" value="雞" v-model="checkboxArray"> <label class="form-check-label" for="check2">雞</label> </div> <div class="form-check"> <input type="checkbox" class="form-check-input" id="check3" value="豬" v-model="checkboxArray"> <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="checkboxArray"> <label class="form-check-label" for="check4">牛</label> </div> <p>晚餐火鍋裡有<span v-for="item in checkboxArray">{{item}}</span>。</p> </div> </div>
|
checkbox
還可以另一種的運用,就是只顯示單選,例如當選擇一個選項就會將 value 綁入 singleRadio 的空字串中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| var app = new Vue ({ el: "#app", data: { singleRadio: "", } }) <div id="app"> <div class="form-check"> <input type="radio" class="form-check-input" id="radio2" value="雞" v-model="singleRadio"> <label class="form-check-label" for="radio2">雞</label> </div> <div class="form-check"> <input type="radio" class="form-check-input" id="radio3" value="豬" v-model="singleRadio"> <label class="form-check-label" for="radio3">豬</label> </div> <div class="form-check"> <input type="radio" class="form-check-input" id="radio4" value="牛" v-model="singleRadio"> <label class="form-check-label" for="radio4">牛</label> </div> <p>晚餐火鍋裡有 {{singleRadio}}。</p> </div>
|
下拉式的選單
當選擇某一個選項時,會將 value 綁入 data 的 selected 空字串中,然後顯示在 {{selected}}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <div id="app"> <h2>喜歡澳洲哪一個城市?</h2> <select name="" id="" class="form-control" v-model="selected"> <option value="" disabled>-- 請選擇地點 --</option> <option value="Melbourne">墨爾本</option> <option value="Sydney">雪梨</option> <option value="Adelaide">阿德雷德</option> </select> {{selected}} </div> <script> var app = new Vue ({ el: "#app", data: { selected: "", } }) </script>
|
component 元件基礎概念
以下有一個範例,當點擊按鈕時,透過 v-on:click
綁定 counter 的按鈕會 + 1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <!-- 當點擊按鈕時,透過 v-on:click綁定counter的按鈕會+1 --> <div id="app"> <div> 目前點擊<button @click="counter += 1">{{counter}}</button>下 </div> </div> <script> let app = new Vue({ el: "#app", data: { counter: 0 } }) </script>
|
如果新增另一個按鈕的話,會怎麼樣呢?
1 2 3 4 5 6 7 8
| <div id="app"> <div> 目前點擊<button @click="counter += 1">{{counter}}</button>下 </div> <div> 目前點擊<button @click="counter += 1">{{counter}}</button>下 </div> </div>
|
因為兩個是共用同一個變數 counter,所以當按其中一個按鈕,兩個會一起 + 1。
那麼如果想要讓個別按鈕資料獨立的話,這邊有另一個方法可以使用:
component 元件,透過這樣的方式,可以讓每個 component 中的 data 都會是互相獨立,看以下範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| // Vue.component(tagName, options) Vue.component('counter-component', { template: `<div> C目前點擊<button @click="counter += 1">{{counter}}</button>下 </div>`, data: function() { return { counter: 0 } }, }); let app = new Vue({ el: "#app", data: { counter: 0 } })
|
tagName 可以取任意的名字,但是要注意必須是小寫,如果是多組字,就要使用 kebab Case 來命名。
option 裡面有 template 跟 data,template 是要顯示在頁面上的樣板,注意要用 `` 包起來,data 在這邊則是 function 並 return 值。
這樣點擊的數量就會是單獨計算,就算再新增一個 component 也一樣會分開計算。
1 2 3 4 5 6 7 8
| <div id="app"> <div> A目前點擊<button @click="counter += 1">{{counter}}</button>下 </div> <!-- 兩者所點擊的數量是分開計算 --> <counter-component></counter-component> <counter-component></counter-component> </div>
|