0%

進階模板語法-01

接續著上一篇的進階模板語法的內容繼續記錄。

反轉陣列元素-透過key

因為Vue在操作DOM元素的時候,是用快速置換的方式操作,導致有些元素不會被置換掉。
所以,我們會透過將key的屬性,來綁定元素某些獨有的屬性,來讓各元素的整體DOM都可以被完整置換。
ex:

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
27
28
29
30
31
32
33
34
---HTML---
<ul>
<li v-for="(item, key) in arrayData" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
</li>
</ul>
<button class="btn btn-outline-primary" @click="reverseArray">反轉陣列</button>

---JavaScript---
var app = new Vue({
el: '#app',
data:{
arrayData:[
{
name: '漂亮阿姨',
age: 24
},
{
name: '小明',
age: 10
},
{
name: '力宏',
age: 35
}
]
},
methods: {
reverseArray: function(){
this.arrayData.reverse()
console.log(this.arrayData)
}
}
})

可以看到以上這個範例,我們在ulli透過v-bind綁上key這個屬性,
而要用item.age去作為key的值,是因為每個元素的age的值都不一樣,所以,可以代表各個的元素,
用這種方式就可以整體置換對應的DOM元素,而不是只有部分的DOM元素被置換。

filter 過濾

以上這個範例,
當你在input欄位輸入內容,並按下enter後,會觸發filterData函式,
此時,會先對dataArray使用filter,當input欄位輸入的內容跟dataArray裡面的元素的name的成員屬性有匹配的話,
就會把那個物件push進去filterArray陣列裡面。
最後,在ul的區塊中去遍歷filterArray陣列裡面的元素,並用該元素的age為索引,
來置換頁面上的DOM內容。

無法運行

在Vue中,不要用將陣列的length直接指定為0的方法,

這樣雖然,陣列的內部會清空,但是,網頁上的DOM是沒有被清空的,還是,維持原樣。
ex: array.length = 0 // 不要這樣操作

要操作Vue陣列內的元素,不能透過索引的方式來操作它

ex:

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
27
28
29
30
31
32
33
---HTML---
<button class="btn btn-outline-primary" @click="cantWork">無法運行</button>
<ul>
<li v-for="(item, key) in arrayData" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
</li>
</ul>

--JavaScript---
var app = new Vue({
el: '#app',
data:{
arrayData:[
{
name: '漂亮阿姨',
age: 24
},
{
name: '小明',
age: 16
}
]
},
methods: {
cantWork: function(){
this.arrayData[0] = {
name: '賽亞人',
age: 100
}
}
}

})

以上這個範例,直接更改arrayData的第一個元素內容,
雖然,該陣列的資料有被修改到,但是,網頁上的DOM內容是沒有被修改到的喔。

Vue.set - 用來修正”無法運行”的問題

我們就可以透過Vue.set來修正在”無法運行”的這個章節中的問題。

以上用Vue.set的寫法,就可以更改陣列中的指定元素之外,也可以連帶更改網頁上的DOM元素內容嘞。

純數字迴圈

可以用v-for來呈現數字。
ex:

1
2
3
4
5
<ul>
<li v-for="item in 10">
{{item}}
</li>
</ul>

以上的內容就會呈現1 - 10的數字

Template的運用

今天我們要一次將陣列的內容,輸入到兩個tr裡面時,我們就可以使用template的技巧
ex:

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
27
28
29
30
31
32
33
34
35
36
---HTML---
<div id="app">
<table class="table">
<thead>
<tr>
<th>姓名</th>
<th>分數</th>
</tr>
</thead>
<tbody>
<template v-for="(item, index) in arrayData" :key="index">
<tr>
<td> {{ item.name }}</td>
<td> {{ item.age }}</td>
</tr>
</template>
</tbody>
</table>
</div>

---JavaScript---
var app = new Vue({
el: '#app',
data:{
arrayData:[
{
name: '漂亮阿姨',
age: 24
},
{
name: '小明',
age: 16
}
]
},
})

以上這個範例,就可以看到兩個tr為一組,被包在template裡面。
而這個template是不會呈現在網頁上的喔,並分別在兩個tr裡面呈現元素的age值和name值。
template的好處就是,如果想要重複重現元素的內容在不同區塊裡面的話,
我們就可以利用template把這些不同區塊包裹起來,並把v-for放在template標籤中,
去遍歷陣列,再將遍歷到的目標元素放在應該呈現的區塊中。

v-for和v-if

v-forv-if寫在一起的時候,會先執行v-for的內容,
接著,才執行v-if的語法。

v-for 與 元件

注意!!
現在建議元件使用 v-for來遍歷陣列的時候,都要加上綁定個元素的key屬性
ex:

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
27
28
29
30
---HTML---
<h4>v-for 與 元件</h4>
<ul>
<list-item :item="item" v-for="(item, key) in arrayData" :key="item.age"></list-item>
</ul>

--JavaScript---
Vue.component('list-item', {
template: `
<li>
{{ item.name }} {{ item.age }} 歲
</li>
`,
props: ['item']
});
var vue = new Vue({
el: '#app',
data:{
arrayData:[
{
name: '漂亮阿姨',
age: 24
},
{
name: '小明',
age: 16
}
]
},
})

以上這個範例,就是裡用v-for來遍歷陣列元素,並將key屬性都綁定個元素的age屬性值,
最後,再將其內容渲染到,我們自訂義’list-item’元件上面。

v-if 和 v-else

當鄰近元件的v-if判斷條件不符合時,就會跑到v-else的內容裡面
ex:

1
2
3
4
5
6
<div class="alert alert-success" v-if="isSuccess">成功!</div>
<div class="alert alert-danger" v-else>失敗!</div>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="isSuccess" v-model="isSuccess">
<label class="form-check-label" for="isSuccess">啟用元素狀態</label>
</div>

當點選input欄位的內容,就可以切換isSuccess的值,接著,在div區塊就會靠著v-if去判斷
isSuccess是否為true,若是true,就會呈現成功的區塊內容,若是false,就呈現v-else的內容,
也就是失敗的區塊內容。

使用 template 切換多數 DOM 呈現

template標籤可以使用Vue指令,同時,template不會被呈現在網頁上
ex:

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
27
28
29
30
31
---HTML---
<div id="app">
<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>

<div class="form-check">
<input type="checkbox" class="form-check-input" id="showTemplate" v-model="showTemplate">
<label class="form-check-label" for="showTemplate">啟用元素狀態</label>
</div>
</div>
--JavaScript---
var app = new Vue({
el:'#app',
data:{
showTemplate: false
}
})

利用input欄位,並透過v-model去綁定showTemplate的值。
接著,再將想要呈現的內容包在template標籤裡面,並用v-if去判定showTemplate值。
藉此,利用input欄位,來切換是否要呈現template裡面的內容。

v-else-if語法

其實方法跟v-else很像,只是v-else-if後面也要接判斷式
ex:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link" href="#" @click.prevent="link = 'a'">標題一</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" @click.prevent="link = 'b'">標題二</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" @click.prevent="link = 'c'">標題三</a>
</li>
</ul>
<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>
</div>

以上範例,當你按下某個鈕會改變link的數值,接著,當該link值符合某個判斷式時,就會呈現
該分頁的內容。

KEY屬性

要特別注意Vue裡面的key屬性的用法喔!!!
因為,Vue本身是會快速置換部分的DOM元件,這樣會導致有某些相對應的DOM元件沒有備置換到,
所以,我們也要利用key屬性來綁定相對應的DOM,這樣在置換的時候,才會全部都備置換成
相對應的元件。
ex:

1
2
3
4
5
6
7
8
9
<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>
<button class="btn btn-outline-primary mt-3" @click="toggleLoginType">切換狀態</button>

以上這個範例,對兩個input欄位,分別綁上它們不同的key值,讓在做DOM元素切換的時候,
也會做相對應的input欄位切換。

v-if和v-show的差異

v-show的用法是將不符合判斷式內容的區塊以display:none的方式,讓這個區塊不顯現。
v-if的用法,是將不符合判斷式的區塊,直接消除掉,只留下符合判斷式的區塊,也就是將原始碼中不符合判斷式的部分直接刪除掉。
ex:

1
2
3
4
5
6
<div class="alert alert-success" v-show="isSuccess">成功!</div>
<div class="alert alert-danger" v-show="!isSuccess">失敗!</div>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="isSuccess2" v-model="isSuccess">
<label class="form-check-label" for="isSuccess2">啟用元素狀態</label>
</div>