In this paper, the corresponding source location vue – next/packages/reactivity/SRC/ref. Ts 91 lines

Ref is also a type of reactive data, similar to Reactive. However, REF is usually used to encapsulate simple data, such as Number, String, and Boolean. Reactive can encapsulate only objects, such as Object and Array. If you look at the source code, you can see that ref is actually an instance object of RefImpl, so it’s easy to implement

Let’s do it backwards

Use ref to encapsulate a simple data

const a = ref(0);

effect(() = > {
    console.log(`a.value: ${a.value}`); // a.value: 0
});

a.value = 10; // a.value: 10
a.value = 20; // a.value: 20
Copy the code

The following results can be preliminarily analyzed:

  1. refThe function accepts a value
  2. Accessing a value in a ref requires accessing thevalueTo access
  3. Dependency collection is also required to get and update valuestrackOr trigger an updatetriggerThe operation of the

Based on the above analysis results, the following ideas can be made:

  1. To define arefThe function takes the incoming value, instantiates it, and returns oneRefImplobject
  2. inRefImplThere should be at least one on the classvalueattribute
  3. definevaluegetterAs well assetterIn which to collect dependency triggered update operations and treat the entire instance object astargetThe incoming

Write about the

After completing the above analysis, it is natural to implement ref. The code is relatively simple and should not require much explanation, as shown below

const ref = value= > {
    return new RefImpl(value);
};

class RefImpl {
    constructor(value) {
        this._value = value;
    }

    get value() {
        track(this.'value');
        return this._value;
    }

    set value(newValue) {
        this._value = newValue;
        trigger(this.'value'); }}Copy the code

That’s it, but it’s worth noting that the ref data is actually stored in this._value, and value is accessed because the class defines getters and setters for value, both of which maintain the _value property. It is a kind of proxy relationship, “give me your money and I’ll spend it for you”, “give me your pen and I’ll sign it for you”, this is proxy meaning if you want, you can also implement a version that is accessed via this.iWantThisValue or this.naLaiBaNi

To run the

A quick example of running with the effect part we wrote last time

// test
import { ref } from './ref';
import { effect, track, trigger } from './effect';

const count = ref(1);

effect(() = > {
    console.log(`count.value: ${count.value}`); // count.value: 1
});

count.value = 10; // count.value: 10
count.value = 20; // count.value: 20
Copy the code

Refs can receive objects, and you need to call reactive. There are many other details in the source code, such as this._isRef to avoid repeated declarations of ref variables, and lazy updating of values (only when the data actually changes). It’s just a simple judgment in the setter that doesn’t affect the core functionality, so it’s not implemented

conclusion

In my opinion, REF is much simpler than reactive and Effect before. There are not too many details to think about (because I am lazy, I do not need to think about so much). The core implementation is also very simple and crude