把流程簡單化的好處很多,但風險是會忘記複雜的事情怎麼做。
如果要把一個陣列或物件渲染到畫面,在原生的 JS 我們可以用迴圈或 forEach 以遍歷的方式將陣列的資料顯示,如果用 ES6 就可用 for...of 循環語句。在 Vue 裡要遍歷陣列的方法並不難,只是遍歷陣列和物件的方式稍有些不同。
去 codepen 看看效果
以 v-for 遍歷陣列的渲染
陣列列表顯示的方法是使用
v-for
指令,在遍歷的時候語法為
<li v-for="(person, index) in persons" :key="index"></li>
在使用
v-for
時要記得加上
:key
讓單筆的屬性有唯一值,這個陣列的唯一值是 index。
在上面的語法範例,可以想成是
<li v-for="(陣列裡的person, 索引值index) in 陣列" :key="index唯一索引值"></li>
。
在寫
v-for
時為了辨識,最好以單、複數來分別,在很多筆的資料裡(persons)中,每次拿一筆資料(person),而成為
person in persons
。
假設我們有個陣列(其實就是 JSON 格式):
persons: [
name: 'Ayda',
age: 18,
name: 'Tracy',
age: 24,
name: 'Kira',
age: 42,
在 HTML 我們可以這樣寫,就可以在頁面渲染出陣列的列表:
<li v-for="(person, index) in persons" :key="index">
{{ index }} --- {{person.name}} --- {{person.age}}
以 v-for 遍歷物件的顯示
遍歷物件的方法也陣列差不多,只是物件並沒有索引值,所以唯一值就會抓取 key 值,如:
v-for="(value, key) in persons[1]" :key="key"
可以想成:
v-for="(value屬性值, key屬性鍵值) in persons物件[1]" :key="key唯一鍵值"
每一個 key 值都需不相同。另外,遍歷物件的功能並不常用。
<!-- 提取單筆 -->
<!-- <li v-for="(value, key) in persons[1]" :key="key">{{value}} -- {{key}}</li> -->
<!-- 提取全部 -->
<li v-for="(value, key) in persons" :key="key">{{value}} -- {{key}}</li>
是改變了陣列本身還是陣列內部的資料?
在 Vue 裡要做到刪除、更新、增加陣列必須先了解 Vue 的運作,要先分清楚我們所操作的是否有改變到陣列本身?還是更改到陣列內部的物件或內容。
例如,如果我們使用this.persons = []
我們把空陣列指向 persons
物件,陣列因此成為空陣列,這樣的動作是有更動到陣列「本身」。但是如果只是去改變陣列內物件的屬性、值,這就只有更動到陣列內部結構。這樣的內部結構改變 Vue 無法知道。
Vue 只會監視 persons 這個陣列的改變,而不會監視陣列內部資料的改變。
let obj = {}; // 改變物件本身
obj.t = 1; // 只改變了物件的內部結構資料
變異方法對原生陣列方法進行包裹
解決的方法是使用 Vue 的「變異方法」 (mutation method)。
在 Vue 的官網上,列表渲染裡的「陣列更新檢測」有寫到,Vue 會將被偵聽的陣列的變異方法進行包裹,然後才將會觸發頁面的部分更新。
陣列裡有這些函式可改變陣列的內部結構,在 Vue 裡用這些方法時,如增加、刪除,用這些方法已不是 JS 的原生方法,而是 Vue 有特殊處理包裹過,包裹的過程會經過兩個步驟:呼叫原生方法函式與更新頁面,也就是 Vue 重寫了一遍這些方法,讓這些方法可以檢測到陣列內部資料的變化。如果 Vue 沒做這些包裹處理,那麼 Vue 就無法檢測到陣列內部資料的變化。
在做陣列內部資料的更動更新,一定要使用以下這些方法,才能讓陣列內部資料變化,自動更新到頁面上。
這些被 Vue 重新包裹過的方法成為「變異方法」有:push()
、pop()
、shift()
、unshift()
、splice()
、sort()
、reverse()
其中,splice()
的功能很強大,可以一次辦到增加、刪除、修改。
刪除、更新、增加的寫法
以範例來說,我們先在頁面增加三個分別為刪除、更新、增加的按鈕,(如何綁定元素明天再來說~)這個範例只是簡單的介紹其運作的方法。
<li v-for="(person, index) in persons" :key="index">
{{ index }} --- {{person.name}} --- {{person.age}} --<button
@click="deletePerson(index)"
Delete
</button>
<button @click="updatePerson(index, {name:'Fanny', age: 25})">
Update
</button>
再來我們來看在 Vue 裡的刪除、更新、增加這三個方法在 Vue 實例裡怎麼寫:
const vm = new Vue({
methods: {
// 刪除
deletePerson(index) {
this.persons.splice(index, 1)
// 更新
updatePerson(index, newPerson) {
// this.persons[index] = newP
// 這樣的做法因為無原生陣列函式,所以在Vue 不會起作用,也不會自動更新頁面
// console.log(this.persons[index], newP)
this.persons.splice(index, 1, newPerson)
// 增加
addPerson(newPerson) {
this.persons.push(newPerson)
如果熟悉上面的操作,應該就可以試著寫出一個簡單的 todoList 了。
每日一句法文有益身心:Merde ! --> 妹.喝.的! -->原意是拉屎的意思!跟英文的 Shit 一樣。
列表渲染 — Vue.js
ES6-遍曆數組 JavaScript
ES5 和 ES6 數組遍歷方法詳解