key和數(shù)組方法

key

vue官網(wǎng)推薦我們使用v-for時(shí),給每一個(gè)節(jié)點(diǎn)元素添加一個(gè)唯一的 key,其實(shí)不只是vue,react中在執(zhí)行列表渲染時(shí)也會(huì)要求給每個(gè)組件添加上key這個(gè)屬性。

要了解key的作用,首先我們要簡(jiǎn)單了解一下虛擬DOM的Diff算法

vue和react都實(shí)現(xiàn)了一套虛擬DOM,使我們可以不直接操作DOM元素,只操作數(shù)據(jù)便可以重新渲染頁(yè)面。而隱藏在背后的原理便是其高效的Diff算法。

 vue和react的虛擬DOM的Diff算法大致相同,其核心是基于兩個(gè)簡(jiǎn)單的假設(shè):

1. 兩個(gè)相同的組件產(chǎn)生類似的DOM結(jié)構(gòu),不同的組件產(chǎn)生不同的DOM結(jié)構(gòu)。

2. 同一層級(jí)的一組節(jié)點(diǎn),他們可以通過(guò)唯一的id進(jìn)行區(qū)分。

基于以上這兩點(diǎn)假設(shè),使得虛擬DOM的Diff算法的復(fù)雜度從O(n^3)降到了O(n)。

好吧,這樣解釋,似乎有點(diǎn)籠統(tǒng)了,我們來(lái)看一個(gè)例子:

我們希望可以在B和C之間加一個(gè)F,

key1.png

Diff算法默認(rèn)執(zhí)行起來(lái)是這樣的:

key2.png

就是C更新成F,D更新成C,E更新成D,最后再插入E

所以我們需要使用key來(lái)給每個(gè)節(jié)點(diǎn)做一個(gè)唯一標(biāo)識(shí),Diff算法就可以正確的識(shí)別此節(jié)點(diǎn),找到正確的位置區(qū)插入新的節(jié)點(diǎn)。

key3.png

所以一句話,key的作用主要是為了高效的更新虛擬DOM

寫(xiě)一個(gè)案例:

 <div id="app">
     <ul>
         沒(méi)有加key
         <li v-for="item in arr">
             <input type="checkbox"/>{{item}}
         </li>
         <button @click="add">添加</button>
     </ul>

     <ul>
         沒(méi)有加key
         <li v-for="item in arr" :key="item">
             <input type="checkbox"/>{{item}}
         </li>
         <button @click="add">添加</button>
     </ul>
</div>
<script>
    new Vue({
        data(){
            return{
                arr:["a","b","c","d","e"]
            }
        },
        methods:{
            add(){
                this.arr.splice(2,0,'f')
            }
        }
    }).$mount("#app")
</script>

先選中C,當(dāng)沒(méi)有加key的插入F的時(shí)候,選中的狀態(tài)變化

key4.gif

可以看的出來(lái),算法是直接將C變成了F

那么我們?cè)賮?lái)看下,加了key的效果:


key5.gif

加了,算法可以準(zhǔn)確無(wú)誤的在b和c之間添加了一個(gè)f

數(shù)組方法

當(dāng)數(shù)據(jù)發(fā)生變化時(shí),Vue會(huì)自動(dòng)檢測(cè)數(shù)據(jù)的變化,視圖會(huì)發(fā)生對(duì)應(yīng)的更新。

Vue中包含了一組觀察數(shù)組編譯的方法,使用它們改變數(shù)組也會(huì)觸發(fā)視圖的更新

變異方法:會(huì)改變?cè)紨?shù)組

數(shù)組方法1.png

非變異方法:不會(huì)改變?cè)紨?shù)組,但是會(huì)返回一個(gè)新數(shù)組

  • fliter()
  • slice()
  • concat()
<div id="app">
    <ul>
        <li v-for="item in arr" :key="item">{{item}}</li>
        <button @click="add()">添加</button>
    </ul>
</div>
<script>
    new Vue({
        data(){
            return{
                arr:["王者榮耀","絕地求生","c","d","e"]
            }
        },
        methods:{
            add(){
                // push
                // this.arr.push("全軍出擊", "aa0", "bb");

                // pop
                // this.arr.pop()

                // shift 刪除數(shù)組中的第一個(gè)元素
                // this.arr.shift()

                // 
                // this.arr.unshift("123")

                // this.arr.splice(1,2)
                // this.arr.splice(1,0, "456","567")

                // this.arr.splice(1,2, "456","567")

                // 這樣修改數(shù)組中的元素,視圖是不會(huì)更新的
                // this.arr[1] = "999"

                // 使用vue的set方法更新
                // 全局set
                // Vue.set(this.arr, 1, "999")
                // 當(dāng)前實(shí)例set

                this.$set(this.arr, 1, "888")

            }
        }
    }).$mount("#app")
</script>

直接修改數(shù)組中的元素,視圖是不會(huì)更新的,需要用到Vue中的set方法

// 這樣修改數(shù)組中的元素,視圖是不會(huì)更新的
// this.arr[1] = "999"

// 使用vue的set方法更新
// 全局set
// Vue.set(this.arr, 1, "999")

// 當(dāng)前實(shí)例set
this.$set(this.arr, 1, "888")
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容