$set 的实现原理

vm.$set( target, propertyName/index, value )

源码:

export function set (target, key, val){
    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
}

其中 defineReactive 函数主要是利用 Object.defineProperty 函数作用于对象属性的值,进行取值和赋值操作时的拦截和处理。

实现流程图

你可能感兴趣的:( $set 的实现原理)