实现Ref
ref
的本质就是通过类属性访问器来实现,可以将一个普通值类型进行包装import { hasChanged, isObject } from "@vue/shared"; import { track, trigger } from "./effect"; import { TrackOpTypes, TriggerOpTypes } from "./operations"; import { reactive } from "./reactive"; export function ref(value) { // ref Api return createRef(value); } export function shallowRef(value) { // shallowRef Api return createRef(value, true); } function createRef(rawValue, shallow = false) { return new RefImpl(rawValue, shallow) } const convert = (val) => isObject(val) ? reactive(val) : val; // 递归响应式 // 实现类 class RefImpl { private _value; // 保存值 public readonly __v_isRef = true; // 标识是ref constructor(private _rawValue, public readonly _shallow) { // 初始化value this._value = _shallow ? _rawValue : convert(_rawValue) } get value() { // 依赖收集 track(this, TrackOpTypes.GET, 'value'); return this._value; } set value(newVal) { if (hasChanged(newVal, this._rawValue)) { this._rawValue = newVal; // 保存值 this._value = this._shallow ? newVal : convert(newVal); // 触发更新 trigger(this, TriggerOpTypes.SET, 'value', newVal); } } }
实现toRefs
标签:toRefs,return,object,value,newVal,源码,._,ref From: https://www.cnblogs.com/dgqp/p/17378587.html使用:将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的
ref
。每个单独的ref
都是使用toRef()
创建的。const state = reactive({ foo: 1, bar: 2 }) const stateAsRefs = toRefs(state) /* stateAsRefs 的类型:{ foo: Ref<number>, bar: Ref<number> } */ // 这个 ref 和源属性已经“链接上了” state.foo++ console.log(stateAsRefs.foo.value) // 2 stateAsRefs.foo.value++ console.log(state.foo) // 3 // 解构使用 function useFeatureX() { const state = reactive({ foo: 1, bar: 2 }) // ...基于状态的操作逻辑 // 在返回时都转为 ref return toRefs(state) } // 可以解构而不会失去响应性 const { foo, bar } = useFeatureX()
class ObjectRefImpl{ public readonly __v_isRef = true constructor(private readonly _object, private readonly _key) {} get value(){ return this._object[this._key] } set value(newVal){ this._object[this._key] = newVal } } export function toRef(object,key){ return new ObjectRefImpl(object,key); } export function toRefs(object) { const ret = isArray(object) ? new Array(object.length) : {}; for (const key in object) { ret[key] = toRef(object, key) } return ret; }
这样就可以将对象的属性转化为
ref
属性。