Reactive has a restriction on the type passed in: it must be an object or an array. Basic types such as String, number, Boolean, and so on are not supported. To use the ActiveAPI, these basic types must be encapsulated as objects, which is obviously not very scientific. So Vue 3.0 provides a refAPI.

A Ref is an interface that essentially has a value attribute that can fetch and assign values.

export interface Ref<T = any> { value: T _shallow? : boolean }Copy the code

ref

Usage scenarios

Turn data into responsive data.

Code explanation:

  1. throughrefTurns the string into oneResponsive objectperson;
  2. throughperson.valuetopersonTo set the new value, also throughperson.valueTo obtainResponsive objectpersonThe value of the.

Realize the principle of

  • createRefIf the parameter passed is alreadyrefObject is returned directly; If not, use itRefImplEncapsulate.

  • RefImplThere are two private variables_valueand_rawValue._rawValueIs the original value,_valueIs the value of the operation.
    • ifvalueValues are raw data,_valueand_rawValueWill be equal tovalue;
    • ifvalueValues are arrays or objects,_valueIs converted toreactiveResponsive object,_rawValueThat’s the original object of the reactive object;
    • getThe function collects dependencies and then returns them_valueIs the value of the operation;
    • setThe function checks to see if the original value has changed and sets it if it has_valueand_rawValueAnd then distribute the dependencies.

refandreactiveSome questions about that?

Question 1: refAPI is used when basic type data is changed to a responsive object, and reactiveAPI is used when an object or array is changed to a responsive object?

Answer 1: This is usually the case, but refs can also turn objects or arrays into reactive objects because their internal implementation is based on Reactive.

Question 2: Since refS include functions of Reactive, why not just provide refAPI?

A feature of ref is that it provides a set method, which can completely replace the value of the original data, similar to let. Reactive cannot operate in this way. Only the attributes of the original value can be modified, similar to the limitation of const.

That is, a REF is like a let, and a Reactive is like a const. They work in different scenarios.

shallowRef

Usage scenarios

Only the replacement of the monitoring object is required, and no modification of the properties of the monitoring object is required. The effect of the original data types shallowRef and ref is no different.

const p1 = {name: "hehe"}; const p2 = {name: "xixi"}; // Const person = shallowRef(p1); person.value.name = "haha"; Person. value = p2; // Data changes will be detectedCopy the code

Reactive does not have replacement objects, so shallowReactive can detect changes in external properties, but not internal properties.

Realize the principle of

  • shallowRefObjects will not be converted toreactiveObject, onlyvalueThe dependency is not distributed until the value changes.

Name = “haha” hasChanged(newVal, this._rawValue) after setting the new value should be true to distribute dependencies.

Person.value. name = “haha” where the get method is called, the GET method is called, and the GET method is called. It has nothing to do with the set method

When is the set method called? Person. value = p2; This way. I hope I didn’t get dizzy

isRef

Usage scenarios

Determines whether an object is a ref object

Realize the principle of

  • isRefIt’s simple. It’s judgment__v_isRefWhether it istrue. becauseRefImplthe__v_isRefistrue.

unref

Usage scenarios

Gets the _value of the ref object, possibly a reactive object (because it does not get the _rawValue).

Realize the principle of

toRef

Usage scenarios

Create a REF object from an attribute of a reactive object for easy assignment and evaluation.

Const zhangshanfeng = reactive ({name: zhang sanfeng, age: 100, child: {name: 'Zhang Cuishan, age: 40, child: {name: zhang mowgli, age: 20 } } }) const wuji = toRef(zhangshanfeng.child, 'child'); // get wuji.value.age += 10; // Change the age of Zhang WujiCopy the code

The main function of this API is to extract part of the reactive data into a REF object for easy manipulation when only part of the data needs to be manipulated. Case if you operate zhang mowgli’s age must use zhangshanfeng. Child. The child, the age + = 10, more complicated.

This interface is also more suitable for network request return value processing, may be in some requests only part of the data is needed to display, this part of the processing is extracted.

Realize the principle of

  • withObjectRefImplTo deal withobjectandkey;

  • getIs to takeobjectthekeyProperty value,setIs setobjectthekeyProperty value. Due to theobjectisResponsive object, so what you’re actually calling isResponsive objectthegetandsetMethods.

toRefs

Usage scenarios

Create a REF object for each attribute of a reactive object for easy assignment and evaluation.

Const zhangshanfeng = reactive ({name: zhang sanfeng, age: 100, child: {name: 'Zhang Cuishan, age: 40, child: {name: zhang mowgli, age: 20 } } }) const refs = toRefs(zhangshanfeng); // Get refs for all attributes of Zhang Sanfeng. // Result {name: <ObjectRefImpl>{_object: zhangsanfeng, key: "name"}, age: <ObjectRefImpl>{_object: zhangsanfeng, key: "name"} "age"}, child: <ObjectRefImpl{_object: zhangsanfeng, key: "child"}, }Copy the code

Realize the principle of

  • That is, execute each property individuallytoRefcall

customRef

Customize a ref object to implement your own functionality.

The get method returns the value, and the set method delays setting the value for 200 milliseconds. If a new value is set within 200 milliseconds, the timer is reset for another 200 milliseconds.

function useDebouncedRef(value, delay = 200) {
  let timeout
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          value = newValue
          trigger()
        }, delay)
      }
    }
  })
}
Copy the code

Realize the principle of

  • customRefThe parameters of thetrackandtrigger, respectively,() => trackRefValue(this)and() => triggerRefValue(this), can collect and distribute dependencies,customRefHolding the returned objectgetandsetMethods, these two methods are the ones that actually perform assignment and evaluation.