六角Vue筆記_進階模板語法介紹

Huang Pei
12 min readFeb 21, 2019

--

動態切換ClassName及Style多種方法/ v-for與其使用細節/ v-if與其使用細節/ Computed 與 Watch

以下筆記出自六角學院課程,詳情請參➤ 六角學院-Vue 出一個電商網站

▶︎ 動態切換 ClassName 及 Style 多種方法

  1. 物件寫法1:直接傳入物件
isTransform: false,
boxColor: false,
_____
<div class=”box” :class=”{‘rotate’:isTransform,’bg-primary’:boxColor}”></div>
_____
<button class="btn btn-outline-primary" @click="isTransform = !isTransform">選轉物件</button><input type="checkbox" class="form-check-input" id="classToggle1" v-model="boxColor"> //checkbox用v-model偵測更改t/f狀態m

2. 物件寫法2:傳入物件變數

*使用-會出錯(bg-danger),要加中括號[‘bg-danger’]

objectClass: {
‘rotate’: false,
‘bg-danger’: false,},
_____
<div class="box" :class="objectClass"></div>
_____
<button class="btn btn-outline-primary" @click="objectClass.rotate=!objectClass.rotate">選轉物件</button><input type="checkbox" class="form-check-input" id="classToggle2" v-model="objectClass['bg-danger']">

3. 陣列寫法,適合class name長度比較不確定的

arrayClass: [‘btn-outline-primary’, ‘active’]
_____
<button class="btn" :class="arrayClass">請操作本元件</button>
_____
<input type="checkbox" class="form-check-input" id="classToggle3" v-model="arrayClass" value="btn-outline-primary"><input type="checkbox" class="form-check-input" id="classToggle4" v-model="arrayClass" value="active">

4. 綁定行內樣式

使用物件的方式加入

styleObject: {
backgroundColor: ‘red’, //-刪除,下個字母大寫
borderWidth: ‘5px’},
styleObject2: {
boxShadow: '3px 3px 5px rgba(0, 0, 0, 0.16)'},
styleObject3: {
userSelect: 'none'}
_____//直接插入物件
<div class="box" :style="{backgroundColor:'red'}"></div>
//插入變數物件
<div class="box" :style="styleObject"></div>
//插入陣列,但裡面要放物件
<div class="box" :style="[{backgroundColor:'red'},{borderWidth:'5px'}]"></div>
<div class="box" :style="[styleObject2, styleObject3]"></div>

*自動加上 Prefix (每個瀏覽器版本結果不同)

▶︎ v-for 與其使用細節

  • 陣列與物件迴圈:v-for可跑陣列也可跑物件,跑物件索引key即物件屬性
0 — 小明 16 歲        → ming — 小明 16 歲
1 — 漂亮阿姨 24 歲 → auntie — 漂亮阿姨 24 歲
2 — 杰倫 20 歲 →jay — 杰倫 20 歲
  • Key(for的場合)

v-for 更新已渲染過的列表時,如果數據項順序改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單復用此處每個元素(默認使用已渲染過的DOM),並且確保它在特定索引下顯示已被渲染過的每個元素。

這個默認的模式是高效的,但只適用不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出。

為了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,需為每項提供一個唯一key 屬性。理想的 key 值是每項都有的唯一 id。

詳細參考

<li v-for=”(item, key) in arrayData” :key=”item.age”>
{{ key }} — {{ item.name }} {{ item.age }} 歲 <input type=”text”>
</li>
<button class=”btn btn-outline-primary” @click=”reverseArray”>反轉陣列</button>
  • filter

-filter(): 建立一個經指定之函式運算後,由原陣列中通過該函式檢驗(判別式)之元素所構成的新陣列。(感覺像是可以使用條件式的map...)

-match(): 方法檢索返回一個字符串匹配正則表達式的的結果。

<input type="text" class="form-control" v-model="filterText" @keyup="filterData"><li v-for="(item, key) in filterArray" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text"></li>
_____
filterArray: [];filterText: '';filterData: function () {
var vm = this;//指向vue物件
vm.filterArray = vm.arrayData.filter(function (item) {
console.log(vm.filterText, item.name,
item.name.match(vm.filterText))
return item.name.match(vm.filterText);});}
//回傳和輸入的內容(名字)條件符合(true)的item,並且產生新陣列filterArray
  • 不能運作的狀況

透過console.log和vue工具看資料都是修改過的,而畫面依然顯示舊資料(視圖無更新)

cantWork: function () {// 情境一:直接修改陣列長度(刪除資料)
this.arrayData.length = 0;
// 情境二:透過索引來取代資料
this.arrayData[0] = {
name: ‘阿強’,
age: 99}
console.log(this.arrayData)}

新增(取代):Vue.set( target, key, value )

向響應式對像中添加一個屬性,並確保這個新屬性同樣是響應式的,且觸發視圖更新。它必須用於向響應式對像上添加新屬性,因為 Vue 無法探測普通的新增屬性 (比如 this.myObject.newProperty = ‘hi’)

刪除:Vue.delete( target, key )

cantWork: function () {// 情境二:
Vue.set(this.arrayData, 0, {
name: '阿強',
age: 99})
console.log(this.arrayData)}
  • 純數字的迴圈
<li v-for=”item in 10"> //輸入數字範圍
{{ item }}
</li>
  • template

當輸出的有特定之格式,可利用template書寫

//將兩個 tr 一組使用 v-for<table class=”table”> <template v-for=”item in arrayData”> //template標籤不會被輸出
<tr><td>{{item.name}}</td></tr>
<tr><td>{{item.age}}</td></tr>
</template>
</table>
  • v-for 與 v-if

v-for搭配 v-if,渲染符合條件的資料

<li v-for=”(item, key) in arrayData” v-if=”item.age<=19">  {{ key }} — {{ item.name }} {{ item.age }} 歲</li>

▶︎ v-if 與其使用細節

  • 使用 v-if, v-else 切換物件呈現
isSuccess: true,<div class=”alert alert-success” v-if=”isSuccess”>成功!</div><div class=”alert alert-danger” v-else>失敗!</div>
  • template使用v-if的場合
<table class=”table”>
<thead>
<th>編號</th>
<th>姓名</th>
</thead>
<template v-if=”showTemplate”>
<tr>
<td>1</td>
<td>安妮</td>
</tr>
<tr>
<td>2</td>
<td>小明</td>
</tr>
</template>>
</table>
  • 切換分頁
// 利用點擊改變linl的值
<li class="nav-item">
<a class="nav-link" href="#" :class="{'active':link==='a'}"
@click.prevent="link='a'">標題一</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" :class="{'active':link==='b'}"
@click.prevent="link='b'">標題二</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" :class="{'active':link==='c'}"
@click.prevent="link='c'">標題三</a>
</li>
// 不同的值渲染出不同的分頁內容
<div class="content">
<div v-if="link==='a'">A</div>
<div v-else-if="link==='b'">B</div>
<div v-else-if="link==='c'">C</div>
  • key(if的場合)

因效能考慮使用局部複用,造成了畫面資訊不一致的狀況,因此使用key使資料一致,key的值若不同,就會重新進行渲染。

* :key 代表的是動態變數,裡面所插入的是 js “變數” 或 “數值”,若非索引的值,則必須是有被宣告的變數,如: v-for=”(item, m) in array” 這樣才能運作。

<template v-if=”loginType === ‘username’”>
<label>Username</label>
<input class=”form-control” placeholder=”Enter your username” :key=”1">
</template>
<template v-else>
<label>Email</label>
<input class=”form-control” placeholder=”Enter your email address” :key=”2">
</template>
  • v-if v.s v-show

-v-if: 直接增加或移除DOM元素。

-v-show: 利用display: block/none來操作是否顯示,程式碼依然存在。

▶︎ Computed 與 Watch

  • Computed: 透過變數將運算的結果呈現於畫面上
// 依照輸入內容過濾資料
<li v-for="(item, key) in filterArray" :key="item.age">
computed: {
filterArray:function(){
var self=this;
return this.arrayData.filter(function(item){
return item.name.match(self.filterText)})
}}
// 抓取現在時間{{formatTime}}computed: {
formatTime: function () {
var now = new Date();
var year=now.getFullYear();
var month=now.getMonth();
var date=now.getDate();
var hour=now.getHours();
var minutes=now.getMinutes();
var seconds=now.getSeconds();
return `${year}/${month}/${date} ${hour}:${minutes}:${seconds}`}}
  • Watch: 監控特定變數,當該變數產生變化時,可執行特定事件
trigger: false
_____
<div class=”box” :class=”{‘rotate’: trigger}”></div>
<button class=”btn” @click=”trigger=true”>Counter</button>
watch: {
trigger: function () { //trigger為data中宣告的變數
setTimeout(() => {
this.trigger=false}, 3000);
}}
//使用 trigger 來觸發旋轉 box、並在3秒後改變回來

--

--

Huang Pei

記錄用倉庫,歡迎指正。菜鳥前端,最菜的那種(超能力少女です)。