Vue3.0 響應式原理

var toProxy = new WeakMap() // 存儲已代理的對象

function reactive(target) {
    if(!isObject(target)) {
        return target
    }

    if(toProxy.get(target)) {
        return toProxy.get(target)
    }

    const handler = {
        get(target, key, receiver) {
            const res = Reflect.get(target, key, receiver)
            return isObject(res) ? reactive(res) : res // 遞歸
        },
         
         set(target, key, value, receiver) {
             var oldVal = target[key]
             var hadKey = hasOwn(target, key)
             if(oldVal === value) {
                 return true
             }
             var extraInfo = { oldVal, newVal: value}
             // 自身屬性才觸發
             if(!hadKey) {   
                 trigger('ADD', extraInfo)
             } else if(value !== oldVal) {
                 trigger('SET', extraInfo)
             }
             return Reflect.set(target, key, value, receiver)
         },

         deleteProperty(target, key) {
             const hadKey = hasOwn(target, key)
             const oldVal = target[key]
             const res = Reflect.deleteProperty(target, key)
             if(hadKey) {
                 trigger('DELETE', key)
             }
             return res
         },
            
         has(target, key) {
             const res = Reflect.has(target, key)
             return res
         },

         ownKeys(target) {
             return Reflect.ownKeys(target)
         }

    }

    let observed = new Proxy(target, handler)
    toProxy.set(target, observed)

    return observed
}

function trigger(str, extraInfo) {
    console.log('render update', 'str-->', str, 'extraInfo-->', extraInfo)

}

function isObject(val) {
    return val !== null && typeof val === 'object'
}

function hasOwn(val, key) {
    return Object.prototype.hasOwnProperty.call(val, key)
} 



// 測試
var testObj = {
  class: '六年級',
  parent: {
    name: 'LiSi',
    age: 30
  },
  scope: [80,90]
}
var p = reactive(testObj)

相關原理能夠看下這篇文章https://juejin.im/post/5d99be7c6fb9a04e1e7baa34?utm_source=gold_browser_extensionreact

相關文章
相關標籤/搜索