Vue.js中提供了一些方法來(lái)動(dòng)態(tài)地修改響應(yīng)式對(duì)象中的屬性值。其中,$set方法可以添加新的屬性并響應(yīng)地更新視圖。本文我們將深入探究Vue.js $set方法的源碼實(shí)現(xiàn)。
首先,我們知道$set方法是Vue實(shí)例的一個(gè)屬性,它是通過(guò)Vue.set方法實(shí)現(xiàn)的。Vue.set方法主要是將響應(yīng)式對(duì)象上的屬性設(shè)置為新值。具體的源碼如下:
export function set (target: ArrayObject, key: any, val: any): any { if (process.env.NODE_ENV !== 'production' && (isUndef(target) || isPrimitive(target)) ) { warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`) } if (Array.isArray(target) && isValidArrayIndex(key)) { target.length = Math.max(target.length, key) target.splice(key, 1, val) return val } if (key in target && !(key in Object.prototype)) { target[key] = val return val } const ob = (target: any).__ob__ if (target._isVue || (ob && ob.vmCount)) { process.env.NODE_ENV !== 'production' && warn( 'Avoid adding reactive properties to a Vue instance or its root $data ' + 'at runtime - declare it upfront in the data option.' ) return val } if (!ob) { target[key] = val return val } defineReactive(ob.value, key, val) ob.dep.notify() return val }
從源碼可以看出,$set方法的源碼實(shí)現(xiàn)主要有以下幾步:
- 通過(guò)判斷target的類型來(lái)避免傳入非法參數(shù)。
- 當(dāng)target是一個(gè)數(shù)組的時(shí)候,我們可以通過(guò)splice方法來(lái)修改數(shù)組項(xiàng),同時(shí)更改目標(biāo)數(shù)組的長(zhǎng)度。
- 當(dāng)target是一個(gè)對(duì)象,并且key是對(duì)象上原有的屬性,則可以直接設(shè)置對(duì)象的屬性值。
- 當(dāng)target沒有__ob__屬性的時(shí)候,可以通過(guò)直接設(shè)置屬性來(lái)實(shí)現(xiàn)屬性的添加。
- $set方法最后一步是通知Observer來(lái)更新視圖。