← 返回首页
Vue3基础教程(三十五)
发表时间:2021-08-14 01:53:16
自定义ref和shallowRef

1.自定义shallowRef

/*
自定义shallowRef
*/
function shallowRef(target) {
    const result = {
        _value: target, // 用来保存数据的内部属性
        _is_ref: true, // 用来标识是ref对象
        get value () {
            return this._value
        },
        set value (val) {
            this._value = val
            console.log('set value 数据已更新, 去更新界面')
        }
    }
    return result
}

/* 测试自定义shallowRef */
const obj = shallowRef({
    a: 'abc',
})

console.log(obj);
//ref3.value = 'xxx' //可以劫持
//console.log(ref3);
obj.value.a = 'yyy' //无法劫持
console.log(obj);

2.自定义ref

let reactiveHandler = {
    get: function (target, key) {
        if (key === '_is_reactive')
            return true;
        return Reflect.get(target, key);
    },
    set: function (target, key, value) {
        var result = Reflect.set(target, key, value);
        console.log('数据已更新, 去更新界面');
        return result;
    },
    deleteProperty: function (target, key) {
        var result = Reflect.deleteProperty(target, key);
        console.log('数据已删除, 去更新界面');
        return result;
    },
};

/*
自定义reactive
*/
function reactive(target) {
    if (target && typeof target === 'object') {
        if (target instanceof Array) { // 数组
            target.forEach((item, index) => {
                target[index] = reactive(item)
            })
        } else { // 对象
            Object.keys(target).forEach(key => {
                target[key] = reactive(target[key])
            })
        }
        const proxy = new Proxy(target, reactiveHandler)
        return proxy
    }
    return target
}

/*
自定义ref
*/
function ref(target) {
    if (target && typeof target==='object') {
        target = reactive(target)
    }

    const result = {
        _value: target, // 用来保存数据的内部属性
        _is_ref: true, // 用来标识是ref对象
        get value () {
            return this._value
        },
        set value (val) {
            this._value = val
            console.log('set value 数据已更新, 去更新界面')
        }
    }

    return result
}

/* 测试自定义ref */

const obj = ref({
    a: 'abc',
    b: [{x: 1}],
    c: {x: [11]},
})

console.log(JSON.stringify(obj));
obj.value.b[0].x++   //可以劫持
obj.value.c.x[0]++   //可以劫持
console.log(JSON.stringify(obj));