0%

Vue 筆記 - 動態產生多筆資料於網頁上 v-for、v-if

vue.js

data 中除了之前所放入的屬性與資料內容外,也可以放入 JSON 的資料結構。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var vm = new Vue({
el: "#app",
data: {
list: [
{
name: "Min",
age: 56,
},
{
name: "Tim",
age: 55,
},
{
name: "Joshua",
age: 20,
},
],
},
});

v-for

這次要透過列表的方式將 JSON 資料呈現在網頁上,傳統 jQuery 可能要寫很多的 li 才能實現此畫面,透過 Vue 只要寫這樣:

1
2
3
<ul>
<li v-for="item in list">{{item.name}}</li>
</ul>

說明:
透過 v-for 指令 ( 同等於 JS 的 for 迴圈篩選資料 ) 來取得資料,item 為自訂義的資料名稱,也就是指的是 data 中每一筆的物件資料,list 指的就是 JSON 本身,白話文可以解釋成:透過 v-for 從 list 篩選出每一筆的 item 資料內容,大括號指的是資料中的屬性。

加入索引 index

如果要加入索引,可以這樣寫:

1
2
3
4
5
<ul>
<li v-for="(item, index) in list" :key="index">
{{ index +1 }} - {{ item.name }} 是 {{item.age}} 歲
</li>
</ul>

要記得索引是從 0 開始,如果要讓使用者從 1 開始,要設定成 index +1

CodePen:

其實現在編輯器相當人性,只要在 li 輸入 v-for,按下 tab,就會跳出預設的格式,再修改成自己要的對應名稱即可。

v-if

簡單來說就是在 HTML 標籤中加入判斷式,以上方例子為例,倘若今天要判斷年紀超過 20 歲的人物顯示在網頁上。

1
2
3
4
5
<ul>
<li v-for="(item, index) in list" :key="index" v-if="item.age > 20">
{{ index +1 }} - {{ item.name }} 是 {{item.age}} 歲
</li>
</ul>

補充觀念

官網不推薦同時使用 v-ifv-for,原因是 v-for 的權重比較高。可看官網的指令說明渲染列表說明,通常 v-if 會與 v-show 一起使用,這後面會提到。

v-for 列表渲染

li 建立 v-for 指令,讓 li 產生多個清單,再透過雙向綁定的方法,使得 HTML 的程式碼很乾淨。

1
2
3
4
5
<ul id="ex1">
<li v-for="item in List">
{{item.msg}}
</li>
</ul>

itemList 中的清單資料,並且透過 data 中的 List 資料內容,同步到頁面上,這個列表不管是 HTML 或是資料的程式碼都乾淨且不會搞混。

1
2
3
4
5
6
7
8
9
10
11
12
13
var vm = new Vue({
el: "#ex1",
data: {
List: [
{
msg: "Good",
},
{
msg: "Wonderful",
},
],
},
});

Codepen https://codepen.io/hnzxewqw/pen/xxwRVaZ

實際範例:今日要查找公司的銷售員名單,並且有編號在前。

HTML

1
2
3
4
5
6
7
8
9
10
<div id="app">
<ul>
<li v-for="(s, index) in sales">
<h3>{{ index }} {{ s.name }}: </h3>
<div>age: {{ s.age }}</div>
<div>company: {{ s.company }}</div>
<div>email: {{ s.email }}</div>
</li>
</ul>
</div>

JavaScript

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
37
var vm = new Vue({
el: "#app",
data: {
sales: [
{
age: 26,
name: "Sarah Zamora",
company: "ZINCA",
email: "sarah_zamora@zinca.ca",
},
{
age: 37,
name: "Cameron Wilder",
company: "NIKUDA",
email: "cameron_wilder@nikuda.biz",
},
{
age: 40,
name: "Roach Hubbard",
company: "EMOLTRA",
email: "roach_hubbard@emoltra.me",
},
{
age: 38,
name: "Juliet Sykes",
company: "PROWASTE",
email: "juliet_sykes@prowaste.org",
},
{
age: 21,
name: "Jerri Jimenez",
company: "ACCUPHARM",
email: "jerri_jimenez@accupharm.tv",
},
],
},
});

Codepen https://codepen.io/hnzxewqw/pen/VwvmjKy

或是做有分頁的選單也很不錯,

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">

<ul>
<li class="pager"><a href="#"> &lt; </a></li>

<li class="pager" v-for="n in 10">
<!-- n 從 1 開始計算 -->
<a href="#">{{ n }}</a>
</li>

<li class="pager"><a href="#"> &gt; </a></li>
</ul>

</div>

Codepen https://codepen.io/hnzxewqw/pen/yLYVJEO

雖然 vue 裡面沒有寫東西,但因為要套用指令效果,所以在 script 中還是要寫入 vue。

v-for + key

加上 key 是考量到效能,在預設狀況下,Vue.js 會盡量重複使用已經渲染好的元素,若不設定 key,不會重新渲染,只會部分更新。故當元素更新時 ( 例如:改變順序 ) 有可識別唯一性的 key 可以確保列表有重新渲染

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
<h1>filtered by age less then 40: </h1>

<ul>
<li v-for="(s, index) in filteredSales" :key="s.name">
<h3>{{ index }} {{ s.name }}: </h3>
<div>age: {{ s.age }}</div>
<div>company: {{ s.company }}</div>
<div>email: {{ s.email }}</div>
</li>
</ul>

</div>

JavaScript

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
37
38
39
40
41
42
43
var vm = new Vue({
el: "#app",
computed: {
filteredSales() {
return this.sales.filter((d) => d.age < 40);
},
},
data: {
search: "",
sales: [
{
age: 26,
name: "Sarah Zamora",
company: "ZINCA",
email: "sarah_zamora@zinca.ca",
},
{
age: 37,
name: "Cameron Wilder",
company: "NIKUDA",
email: "cameron_wilder@nikuda.biz",
},
{
age: 40,
name: "Roach Hubbard",
company: "EMOLTRA",
email: "roach_hubbard@emoltra.me",
},
{
age: 38,
name: "Juliet Sykes",
company: "PROWASTE",
email: "juliet_sykes@prowaste.org",
},
{
age: 21,
name: "Jerri Jimenez",
company: "ACCUPHARM",
email: "jerri_jimenez@accupharm.tv",
},
],
},
});

v-if / v-else & v-show

大部分 v-ifv-show 會拿來一起使用或比較,兩者最大的差別是在對 DOM 元素的操作。

v-if

會依照條件決定是否將元件渲染在網頁上,並決定事件與資料的監聽是否要綁定至元件或直接銷毀元件。

透過 v-if 加入判斷,倘若條件相符,就顯示於網頁上。

HTML

1
2
3
4
5
6
7
8
<div id="app">

<h1 v-if="option1">Yes</h1>
<hr>

<h1 v-if="option2">Yes</h1>
<h1 v-else>No</h1>
</div>

JavaScript

1
2
3
4
5
6
7
var vm = new Vue({
el: "#app",
data: {
cond1: 1 > 0,
cond2: false,
},
});

Codepen https://codepen.io/hnzxewqw/pen/gOaLwpV

v-show

則是一定會產出元件,但以條件來切換 CSS (display:block / none) 的顯示與否。若條件更動頻繁,則適合用此方法。

HTML

1
2
3
4
5
6
7
<div id="app">
<h1 v-if="cond1">Yes</h1>
<h1 v-else>No</h1>
<hr>
<h1 v-show="cond2">Yes</h1>
<h1 v-show="!cond2">No</h1>
</div>

JavaScript

1
2
3
4
5
6
7
var vm = new Vue({
el: "#app",
data: {
cond1: false,
cond2: true,
},
});

Codepen https://codepen.io/hnzxewqw/pen/abvBmNG