As you can see in the title, I gave VUe3 a PR, but it didn’t pass ha ha ha, but I learned a lot during the whole process. I hereby record this rare experience.

Where do PR points come from

I have to mention cui da’s Mini-Vue, which is also the library that brought me into the source world of VUe3.

Through cui Da’s source code course, WHEN I implement unref, I found a problem worth thinking about:

// unref implementation in source code
export function unref<T> (ref: T | Ref<T>) :T {
    return isRef(ref) ? (ref.value as any) : ref
}
Copy the code

As you can see, the source code evaluates the value passed in. If the ref object chooses to return its value attribute, if it is not a REF object, it returns the value passed in.

Unref returns the value passed in when the ref was created.

When I write here, I suddenly feel something is not quite right. After careful recall, I remember a detail in implementing ref:

// source code in the ref class implementation
class RefImpl<T> { 
    private _value: T 
    private _rawValue: T 
    publicdep? : Dep =undefined 
    public readonly __v_isRef = true 
    constructor(value: T, public readonly __v_isShallow: boolean) { 
        this._rawValue = __v_isShallow ? value : toRaw(value) 
        
        // Here is the point, here here
        this._value = __v_isShallow ? value : toReactive(value) 
        // Up is important, up is up
    } 
    get value() { 
        trackRefValue(this) return this._value 
    } 
    set value(newVal) {
        newVal = this.__v_isShallow ? newVal : toRaw(newVal) 
        if (hasChanged(newVal, this._rawValue)) {
            this._rawValue = newVal 
            this._value = this.__v_isShallow ? newVal : toReactive(newVal) 
            triggerRefValue(this, newVal) 
        } 
    } 
}
Copy the code

If ref (or shallowRef) is called, the value passed in will be saved directly. If ref (or shallowRef) is called, the value passed in will be toReactive.

// Implementation of toReactive in source code
export const toReactive = <T extends unknown>(value: T): T =>
  isObject(value) ? reactive(value) : value
Copy the code

Reactive (value) is returned if the value is an object, and value is returned otherwise.

Therefore, when an object is passed in a ref, the value is wrapped in reactive, and the ref.value call is reactive. Very clever, but the problem is that when I call unref(value) to get the “static” value of unref(value), I return the ref.value, which is still a reactive proxy object, not a simple object.

According to my logic, if the user only wants to get the purest object, the realization of this UNref obviously does not meet the expectation. With this determination, I started my PR.

The process of pr

After forking vue3 and pulling it locally, PNPM installed the dependencies and started adding unit tests to ref.spec.ts:

test('unref'.() = > {
  const foo = {
    bar: 1
  }
  expect(isReactive(unref(ref(foo)))).toBe(false) // should not be reactive
  expect(unref(ref(foo))).toBe(foo)
})
Copy the code

By analyzing the requirements, we need to return the original value of the object wrapped in Reactive. It happens that a toRaw method is implemented in Reactive, so I modify the original method:

export function unref<T> (ref: T | Ref<T>) :T {
  // return isRef(ref) ? (ref.value as any) : ref
  return isRef(ref) ? (toRaw(ref.value) as any) : ref
}
Copy the code

Well, the unit tests passed, and THEN I ran the unit tests on all the other modules and they all passed, indicating that the change didn’t affect any other modules.

Done, push to my warehouse, submit pr and start quietly waiting for the VUE team to review the code…

Of course, the results have come out, you don’t have to wait for hahaha, first put a link github.com/vuejs/core/…

The results of the pr

During the process, many contributor raised questions. Some said that THEY could be solved by toRaw(unref(ref)), and some said that my changes would affect the collection of dependencies on computed attributes. Indeed, there would be some problems. But vue3 when designing the function unref, the original intention is to solve the problem, what effect is this function to achieve?

This is not I can answer, have to wait for Utah to come to kangkang hahaha, thinking about this, I feel my PR is mostly cold.

A few days later, as expected, MY PR was personally shut down by Iu, but he also offered an explanation:

What he means is that the unref just wants to get the value of the ref, it doesn’t want to get rid of its responsiveness, it’s consciously designed that way.

Yes, although the heart has a pity, but I can only thanks, I got it., but also really learned a lot, have to say that vue3 design is indeed very exquisite, continue to chew, I still have a long way to go, I hope to conquer VUe3 as soon as possible.

The last

So far, I contact vue3 only half a year or so of time, began to look at the source code, the implementation of simple logic has not been a few months, but really feel a lot of success, really thanks to Cui Da mini-Vue, there is already 4.1K star, improve fast, Cui Da also out of the supporting courses (fees), The price and the market source code course compared to really have no say.

His course is very hardcore, very dry goods, not so friendly to the novice, so that has not been fire up, but the content is really good, and Cui big supporting q&A service, interested in the course of friends can find me to understand ha.