vue使用Object.defineProperty监听数据变化

 

vue如何使用 Object.defineProperty

/**
 *对数组的方法重新定义
 *防止污染原来的数组方法
 */
const oldPropType = Array.prototype;
const newPropType = Object.create(oldPropType);
['push', 'prop', 'shift', 'unshift', 'sort', 'splice', 'reverse'].forEach(method => {
    newPropType[method] = function () {
        oldPropType[method].call(this, ...arguments);
        //重新渲染
        render();
    }
})

/**
 * 获取和设置数据
 * @param bean 数据对象
 * @param key 键
 * @param value 值
 * @returns {*}
 */
function defineReactive(bean, key, value) {
    //递归循环 对象里面的对象
    observer(value);
    //通过defineProperty方法来监听数据变化
    Object.defineProperty(bean, key, {
        get() {
            return value;
        },
        set(newVal) {
            //如何值没有改变则不需要再页面渲染
            if (value === newVal) {
                return
            }
            //把新值赋值给旧值
            value = newVal;
            //执行 渲染函数
            render()
        }
    })
}

/**
 * 观察数据
 * @param data
 */
function observer(data) {
    //判断值是否是数组
    if (Array.isArray(data)) {
        //使用复制的数组方法放入该数据的原型链中,更改原来的原型链中的数组方法
        data.__proto__=newPropType;
        return;
    }
    //如果时对象,则遍历每一个值进行监听是否发生改变
    if (typeof data === 'object') {
        for (const key in data) {
            defineReactive(data, key, data[key]);
        }
    }
}

/**
 * 模拟页面渲染
 */
function render() {
    console.log('页面渲染')
}

/**
 * set方法
 * @param data 修改谁
 * @param key  改什么
 * @param value 改成什么
 * @returns {*}
 */
function $set(data,key,value) {
    if(Array.isArray(data)){
        data.splice(key,1,value)
        return
    }
    defineReactive(data,key,value);
    render()
    return value
}

/**
 * deltet方法
 * @param data 要删除谁
 * @param key  删除什么
 */
function $delete(data,key) {
    if(Array.isArray(data)){
        data.splice(key,1);
        return
    }
    delete data[key]
    render();
}
//模拟vue中的data的数据
const data = {
        name: 'shu',
        obj: {
            age: 12,
            name: 'ce'
        },
        arr:[1,2]
    }
//调用方法 observer()传入要观察的数据
observer(data)

你可能感兴趣的:(vue,vue)