參考官網 https://cn.vuejs.org/v2/guide/list.html
列表渲染 v-for 可使用數組和對象
注1: v-for key 屬性
當 Vue 正在更新使用 v-for 渲染的元素列表時,它默認使用“就地更新”的策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序,而是就地更新每個元素,並且確保它們在每個索引位置正確渲染。
這個默認的模式是高效的,但是只適用於不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出。
爲了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要爲每項提供一個唯一 key 屬性:
<div v-for="item in items" v-bind:key="item.id">
<!-- 內容 -->
</div>
建議儘可能在使用 v-for 時提供 key attribute,除非遍歷輸出的 DOM 內容非常簡單,或者是刻意依賴默認行爲以獲取性能上的提升。
注2:數組更新檢測
Vue 將被偵聽的數組的變異方法進行了包裹,所以它們也將會觸發視圖更新。這些被包裹過的方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
變異方法,顧名思義,會改變調用了這些方法的原始數組。相比之下,也有非變異 (non-mutating method) 方法,例如 filter()
、concat()
和 slice()
。它們不會改變原始數組,而總是返回一個新數組。當使用非變異方法時,可以用新數組替換舊數組:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
注意,由於 JavaScript 限制Vue 不能檢測以下數組的變動,不會觸發響應式更新。
- 當你利用索引直接設置一個數組項時,例如:
vm.items[indexOfItem] = newValue
- 當你修改數組的長度時,例如:
vm.items.length = newLength
注3:對象變更檢測注意事項
還是由於 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 現在是響應式的
vm.b = 2
// `vm.b` 不是響應式的
對於已經創建的實例,Vue 不允許動態添加根級別的響應式屬性。但是,可以使1.用 Vue.set(object, propertyName, value) 方法向嵌套對象添加響應式屬性。
2.你還可以使用 vm.$set 實例方法,它只是全局 Vue.set 的別名:
vm.$set(vm.userProfile, 'age', 27)
3.有時你可能需要爲已有對象賦值多個新屬性,使用 Object.assign() 或 _.extend()。你應該用兩個對象的屬性創建一個新的對象。
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'})
注4:顯示過濾/排序後的結果
有時,我們想要顯示一個數組經過過濾或排序後的版本,而不實際改變或重置原始數據。在這種情況下,可以創建一個計算屬性,來返回過濾或排序後的數組。
例如:
<li v-for="n in evenNumbers">{{ n }}
</li>data: {
numbers: [ 1, 2, 3, 4, 5]},
computed: { evenNumbers: function () {return this.numbers.filter(function (number) { return number % 2 === 0 }) } }
在計算屬性不適用的情況下 (例如,在嵌套 v-for
循環中) 你可以使用一個方法:
<li v-for="n in even(numbers)">{{ n }}
</li>data: { numbers: [ 1, 2, 3, 4, 5] },
methods: { even: function () {return this.numbers.filter(function (number) { return number % 2 === 0 }) } }
注5:注意我們不推薦在同一元素上使用 v-if
和 v-for
。
而如果你的目的是有條件地跳過循環的執行,那麼可以將 v-if 置於外層元素 (或 <template>)上。如:
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
注6:當在組件上使用 v-for
時,key
現在是必須的。
<my-component v-for="item in items" :key="item.id"></my-component>
詳見簡單的 todo 列表的完整例子。