v-for
可以將資料多筆渲染,形式為 :
自訂名稱 in 特定物件。ex : item in products。
這裡將 index (索引值)暫時作為 key。 (後面會說到為何不要這樣做)
<ul>
<li v-for='(item,key) in products':key="key">{{ key+1 }}.{{item.name}} / {{item.price}}元</li>
</ul>
物件迴圈
<ul>
<li v-for='(item,index) in products' :key="index">{{ key+1 }}.{{item.name}} / {{item.price}}元</li>
</ul>
純數值迴圈
<ul>
<li v-for="i in 5">{{ i }}</li>
</ul>
有相同父元素的子元素必須有獨特的 key,重複的 key 會造成渲染錯誤。
也就是說 v-for 的 key 必須是唯一值,如此當我們重新渲染 v-for 列表時,才能夠準確地更新節點。
而這裡的 item.name
就是獨特的,因此可以將它作為key,並用 v-bind
綁定屬性。
v-for 一定會和 key 綁在一起。 (原因後面會提到)
<ul>
<li v-for="(item, key) in products" :key="item.name">
{{ key }} - {{ item.name}} / {{ item.price }} 元
<input type="text">
</li>
</ul>
在開發過程中,當我們遇到 table 或 ul li 列表時,有時候會利用 index 來做為 key 。(默默被戳中)
當 vue 在更新 v-for 渲染的元素時,是默認使用 「就地更新」 的策略,而非移動 DOM。
那這個 「就地更新」 是什麼意思呢? 來舉個例子 :
這是個list,假如我們現在要新增一個 4 在最後面 :
vue 會自動比對舊節點與新節點的內容,而在這個例子中,因為前三項並沒有任何變化,所以這裡只會很單純的新增了一個 「4」 的項目。
那如果我們試著把 4 放到最前面呢?
因為就地更新不會移動 Dom 元素的順序,只會更新內容而已。此時 DOM 元素依然存在。
但原來的項目三的 DOM 已經不夠用了,所以會再新增一個 DOM :
此時 data 和 key 的對應關係已經被改變,因此也會被重新渲染
如果資料很少的話倒是沒什麼差,不過一旦資料多起來,就會對效能造成影響。
因為 v-for 默認使用 「就地更新」 的策略,vue 會根據這個 key 的值 去判斷這個值是否需要被修改。如果需要被修改的話,就重新渲染,如果不用的話,就不動。
如果我們的 v-for 沒有搭配 key 使用,vue 就無法判斷哪個值不用被修改,因此所有資料都會被重新渲染,這樣的行為會造成效能的浪費。
如果有綁 key 的話,vue 會自動比對,如果我們只需要修改某條資料,他就只會去重新渲染那條資訊,進而達成效能的優化。
那如果我們希望既要效能好,又能達到一樣目的的話要怎麼辦呢?
正確的做法是 : 拿唯一值(id)作為key 。
因為 id 是唯一值,因此在 就地更新 時,就會按照 id 來比對,
只要有一樣的 id,就可以避免重複渲染 DOM,進而達成優化效能的效果。
結論 : 所謂就地更新的意思就是 : 只更新需要更新的節點,盡量用原地修改的方式來更新資料。
提醒 :
如果你沒有對資料進行逆序操作 (比如打亂順序,或是倒轉順序),僅僅是用來展示的渲染,這樣的話使用 index 作為key 就沒有問題。
參考文章:
不只懂 Vue 語法:為何 v-for 的 key 必須是唯一值?v-for 與 v-if 能否同時使用?
关于使用index作为key的问题
vue的就地更新策略__前端__Vue.js