利用 WeakMap 對 Vue 新建數組中的對象賦予 :key

需求

在 Vue 中,對組件進行循環都須要加入key以便「就地複用」,但是在某些狀況下,咱們須要新建多個對象,而這些對象不是從後端獲取到的,而是前端生成的,沒有惟一值,且 Vue 目前版本只容許字符串,數字做爲組件的 key。html

方案

簡單的組件

例如前端

<template> 
    <easy-component v-for="(item, index) in items" :key="index"/>
</template>
<script>
    export default{
        methods: {
            addSometing () {
                this.items.push({
                    // 一些屬性
                    someProp
                })
            }
        }
    }
</script>

簡單的組件,對 items 進行 CRUD 都是能夠識別出來。不會影響界面的顯示。es6

複雜的組件

可是對於一些複雜的組件 Vue 是識別不出來的,並且在刪除時候會發生錯亂。
因此須要這樣寫編程

<template> 
    <complex-component v-for="item in items :key="item.id"/>
</template>
<script>
    export default{
        methods: {
            addSometing () {
                this.items.push({
                    id: getUidFunction(),
                    // 一些屬性
                    someProp
                })
            }
        }
    }
</script>

在建立時候添加惟一的 key —— id ,而且在上傳的時候刪除數組的 id後端

缺點

很難判斷你所寫的組件到底是複雜仍是簡單,但在數組對象中添加惟一的 id 且必須在上傳以前去除它,這終究不是一個好的解決方案。數組

更好的方法 WeakMap

思考

在ruby語言中,咱們能夠惟一肯定這個對象,由於每一個對象新建後都有一個惟一值肯定該對象。可是 js 卻沒有這種語言特性。因此咱們要從這方面入手考慮。緩存

WeakMap的做用

WeakMap針對於普通的 Map 有兩點特殊之處
一、WeakMap只接受對象做爲鍵名( null 除外),不接受其餘類型的值做爲鍵名。
二、WeakMap的鍵名所指向的對象是弱引用,不計入垃圾回收機制。
重點在於 若是刪除了WeakMap的鍵名所指向的對象,無需手動刪除應用。
那麼 思考後代碼以下ruby

// 惟一key
let uKey = 1
// 弱引用Map
const uidMap = new WeakMap()

function getUniqueKey (obj) {
    if (!uidMap.has(obj)) {
        uidMap.set(obj, uKey++)
    }
    return uidMap.get(obj)
}

// 爲了簡單直接使用插件
const uidPlugin = {
    install (Vue) {
        Vue.prototype.$uid = getUniqueKey
    }
}

if (typeof window !== 'undefined' && window.Vue) {
    window.Vue.use(uidPlugin)
}

export { uidPlugin }

在複雜的組件能夠這樣使用編程語言

<template> 
    <complex-component v-for="(item, index) in items :key="$uid(item)"/>
</template>

無需添加惟一的 id 以及刪除 id ,即插即用且不影響垃圾回收。完美!ui

WeakMap 其餘使用場景

一、標識 對象
二、緩存與對象相關的 屬性
三、爲對象添加監聽器
具體可參考 Exploring ES6

總結

新的特性對應新的解決方案,雖然js不是一門優秀的編程語言,可是js卻擁有着及其優秀的社區,社區使得js能夠不斷進步。 在這裏我也想求教你們,有沒有什麼更好的解決方案,或者這篇博客中有什麼不對的地方,歡迎指正,在這裏感謝各位了。

相關文章
相關標籤/搜索