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:
ref
The function accepts a value- Accessing a value in a ref requires accessing the
value
To access - Dependency collection is also required to get and update values
track
Or trigger an updatetrigger
The operation of the
Based on the above analysis results, the following ideas can be made:
- To define a
ref
The function takes the incoming value, instantiates it, and returns oneRefImpl
object - in
RefImpl
There should be at least one on the classvalue
attribute - define
value
的getter
As well assetter
In which to collect dependency triggered update operations and treat the entire instance object astarget
The 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