vue2.x响应式原理浅析




    
    Observe demo


    

响应式 demo

function updateView(val) {
    console.log('视图更新', val)
}

// 重新定义数组原型
const arrayProto = Array.prototype
// 创建新对象,原型指向 arrayProto ,再扩展新的方法不会影响原型
const arrayMethods = Object.create(arrayProto);
['push', 'pop', 'shift', 'unshift', 'sort', 'reverse', 'splice'].forEach(methodName => {
    arrayMethods[methodName] = function() {
        arrayProto[methodName].call(this, ...arguments)
        updateView(this)
    }
})

// 监听对象属性
function observer(target) {
    // 不是对象或数组,直接返回
    if (typeof target !== 'object' || target == null) return target
    if (Array.isArray(target)) {
        target.__proto__ = arrayMethods
    } else {
        // 重新定义各个属性(for in 也可以遍历数组)
        for(let key in target) {
            defineReactive(target, key, target[key])
        }
    }
}

// 监听属性的get和set
function defineReactive(target, key, val) {
    // 递归监听子属性(深度监听)
    observer(val)
    Object.defineProperty(target, key, {
        get() {
            return val
        },
        set(newVal) {
            if (newVal !== val) {
                updateView(newVal)
                return newVal
            }
        }
    })
}

const data = {
    name: '张三',
    age: 20,
    obj: {
        address: '北京'
    },
    a: {
        b: {
            c: {
                d: 'dddddddd'
            }
        }
    },
    nums: [4,6,2,7,4,8,1]
}

// 监听data
observer(data)

data.name = '李四'
data.age = 33
data.obj.address = '深圳'
data.a.b.c.d = 'd 改变了'

data.nums.push(6)

data.nums.reverse()
data.nums.sort((a, b) => a - b)

vue2.x响应式原理浅析_第1张图片

你可能感兴趣的:(vue2.x响应式原理浅析)