vue之列表循環


文檔:https://cn.vuejs.org/v2/guide/list.html

當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用“就地復用”策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單復用此處每個元素,並且確保它在特定索引下顯示已被渲染過的每個元素。這個類似 Vue 1.x 的 track-by="$index"

意思就是,默認就是按照索引來“就地復用”html元素的,如以下代碼

<div v-for="(item,index) in arr" :key="index">

等價於

<div v-for="(item,index) in arr">

對於“就地復用”這個現象,以下來重現一下:

測試代碼

<template>
    <div>
        <div v-for="(item,index) in arr">
            <input type="text">
            <button @click="del(index)">刪除</button>
        </div>
        <button @click="add">添加</button>
    </div>
</template>

<script>
    export default {
        name: "App",
        data() {
            return {
                arr: [
                    "1",
                    "2",
                    "3",
                ]
            }
        },
        methods: {
            del(index) {
                this.arr.splice(index, 1);
            },
            add() {
                this.arr.push("");
            }
        }
    }
</script>

往頁面的輸入框依次填入1~3:

然后點擊第二個刪除按鈕,效果如下:

頁面剩下1、2,這跟我們預期的剩下1、3不一樣,原因就在於vue默認的“就地復用”原則。現象解釋如下:

將以上三個輸入框記為a,b,c。for循環默認的key為索引的話,則a對應0,b對應1,c對應2 。那當刪了了第二個元素時,新數組的元素的索引分別為0和1,而重新渲染時,采用就地復用的話,復用到的dom元素就是a和b了,頁面輸入框就展示1和2了。這輸入框中的1和2實際上就是代表了dom的狀態,通過輸入框的值,就能看出來,vue復用了哪個dom元素。這里說的,實際上就是對應了文檔的第二段話:

這個默認的模式是高效的,但是只適用於不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出

也就是說,當dom有狀態的時候,最好就不要采用這種默認模式(key為索引),否則會導致狀態混亂(如上面我們明明點擊了第二個刪除,而頁面展示的效果卻像點擊了第三個刪除的按鈕一樣)。

對於循環渲染有狀態的dom元素,應該讓key與數組元素一一對應起來,這樣數組元素的刪除,就完全等同於對應dom元素的刪除了(換個角度解釋以上的問題就是:點擊刪除的前后,索引1對應着相同的dom元素,而對應的數組元素卻不一致,導致頁面展示的結果讓人困惑),解決辦法如下:

<div v-for="(item,index) in arr" :key="item">
    <input type="text">
    <button @click="del(index)">刪除</button>
</div>

讓key與數組元素唯一對應起來即可,運行效果:點擊第二個刪除,界面上剩余1,3,符合我們預期結果。但是這樣一來,vue就不會就地復用,性能會相對低一點了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM