总结Vue响应式API实现原理之ref

530 阅读1分钟

基础API

ref 函数

使用

image.png

image.png

实现

先打印出来看它有什么东西,暂不探讨值是对象的情况(会在下一章讲reactive的时候一起讲)

const test = ref('a')

console.log(test);

image.png

这可以得出一个结论吧?我们自己可以写一个大概实现如下:

class RefImpl {
    constructor(value) {
        this.dep = new Set(); // 用于收集依赖
        this._v_isRef = true; // 用于判断是否是ref,isRef函数就是利用这个实现的
        this._v_isShallow = null; // 用于判断是ref还是shawllowRef
        this._rawValue = value; // 存放原始值
        this._value = value; // 存放代理值
        this.value = value; // value做数据劫持
    }
}

ref是如何做到响应式的?

ref在处理基本值的时候用的还是改写属性get和set方法的方式,并没有用proxy

tips:reactive的响应式就是利用proxy实现的,ref处理值为对象的情况底层也是调用reactive,这个后面讲...先上代码看ref如何处理基本值:

class RefImpl {
    constructor(value) {
        this.dep = new Set();
        this._v_isRef = true;
        this._v_isShallow = null;
        this._rawValue = value
        this._value = convert(value); // 判断是否是基本值是的话调用reactive处理
    }
    get value() {
        // 收集依赖, dep.add(依赖)
        trackRefValue(this);
        return this._value;
    }

    set value(newValue) {
        // 当新的值不等于老的值的话,
        // 那么才需要触发依赖
        if (hasChanged(newValue, this._rawValue)) {
            // 更新值
            this._value = convert(newValue);
            this._rawValue = newValue;
            // 触发依赖 for(const effect of dep) { effect.run() }
            triggerRefValue(this);
        }
    }
}

总结

其实很难把一个api单独提出来讲,因为相关联的东西太多,只能讲它最表面的东西,如果沿着它的函数调用讲下去其实基本要讲完整一个vue3的响应式原理,这篇文章我希望是让大家对ref有一个最基本的认知吧 2022.5.19 00:42 上海浦东