I. Introduction of REF

Ref is a reactive API in VUe3, which is described in the official documentation as:

It takes an internal value and returns a reactive and mutable REF object. The ref object has a single property.value pointing to an internal value.

In plain English, ref is a function that takes a parameter and returns a responsive object. This responsive object has a value attribute, and the value of the value attribute refers to the passed parameter. Accessing and modifying the value attribute is the same as modifying the original parameter, but REF provides the responsive capability.

Second, source code analysis

// packages\reactivity\src\ref.ts

// ref function definition
export function ref<T extends object> (value: T) :ToRef<T>
export function ref<T> (value: T) :Ref<UnwrapRef<T>>
export function ref<T = any> () :Ref<T | undefined>
export function ref(value? : unknown) {
  return createRef(value} / /createRefThe function definitionsfunction createRef(rawValue: unknown, shallow = false) {// If the value passed is alreadyrefType that returns the value without processingif (isRef(rawValue)) {
    return rawValue} // instantiate oneRefImplObject and returnreturn new RefImpl(rawValue, shallow} / /RefImpl Classdefineclass RefImpl<T> {
  private _value: T

  public readonly __v_isRef = true// Constructor, which takes two arguments // Parameter 1: original value // parameter 2: Yes or noshallowRef
  constructor(private _rawValue: T, public readonly _shallow: boolean) {
    this._value = _shallow ? _rawValue : convert(_rawValue)
  }
  
  // The get method of the value attribute
  get value() {
    // Get a track(i.e. dependency collection)
    track(toRaw(this), TrackOpTypes.GET, 'value')
    // Get returns the original value
    return this._value
  }

  // The set method of the value attribute
  set value(newVal) {
    // Check whether the value has changed, use! == operator comparison
    if (hasChanged(toRaw(newVal), this._rawValue)) {
      // Change the original value
      this._rawValue = newVal
      this._value = this._shallow ? newVal : convert(newVal)
      // Trigger an update notification.
      trigger(toRaw(this), TriggerOpTypes.SET, 'value', newVal)
    }
  }
}
Copy the code

Third, summary

Ref -> createRef -> instantiate RefImpl and return; When RefImpl is instantiated, the get and set methods of value attribute are set to collect and update dependent notifications. The core lies in how track and trigger methods collect and update dependent notifications.