Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is responsive Refs API when Vue 3.0 is advanced

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

In this issue, the editor will bring you what is responsive Refs API about Vue 3.0. the article is rich in content and analyzes and describes it from a professional point of view. I hope you can get something after reading this article.

1. Ref

This function takes an internal value and returns a responsive and mutable ref object with a value property inside.

1.1 examples of use

Const {ref} = Vue const skill = ref ("Vue 3") console.log (skill.value) / / Vue 3 skill.value = "Vite 2" console.log (skill.value) / / Vite 2

1.2 function implementation

/ / packages/reactivity/src/ref.ts export function ref (value: t): ToRef export function ref (value: t): Ref export function ref (): Ref export function ref (value?: unknown) {return createRef (value)}

As you can see from the above code, the value parameter of the ref function supports parameters of non-basic data types as well as basic data types. Inside the ref function, the createRef factory function is called to create the ref object. The createRef function is implemented as follows:

/ / packages/reactivity/src/ref.ts function createRef (rawValue: unknown, shallow = false) {if (isRef (rawValue)) {return rawValue} return new RefImpl (rawValue, shallow)}

When creating a ref object, if you find that the rawValue parameter itself is a ref object, it will be returned directly. Otherwise, the RefImpl constructor is called to create the ref object. Taking the example used by ref as an example, the internal structure of the ref object created through ref ("Vue 3") is shown in the following figure:

From the figure above, we can clearly see that the ref object contains properties such as _ _ v_isRef, _ rawValue, and _ value. So what is the use of these attributes? Here we first introduce the role of the _ _ v_isRef attribute.

II. IsRef

This function is used to check whether the specified value is a ref object.

2.1 examples of use

Const {ref, isRef} = Vue const name = ref ("Po Brother") console.log (isRef (name)) / / true

2.2 function implementation

/ / packages/reactivity/src/ref.ts export function isRef (r: Ref | unknown): r isRef export function isRef (r: any): r isRef {return Boolean (r & & r.__v_isRef = true)}

As you can see from the above code, inside the isRef function, it is through the r & & r.__v_isRef = true expression to determine whether the parameter r is a ref object. Having analyzed the ref function earlier, we already know that the essence of the ref object is an instance of the RefImpl class. So when was the _ _ v_isRef member property on this instance set? Let's find the answer to this question from the source code:

/ / packages/reactivity/src/ref.ts class RefImpl {private _ value: T public readonly _ _ v_isRef = true / / omit most of the code}

Looking at the above code, the _ _ v_isRef property is a public read-only property and its value is always true. OK, now that we've seen how to create a ref object and how to check whether the specified value is a ref object, let's introduce the next function, unref.

III. Unref

This function takes a parameter and returns the internal value of the object if it is a ref object, otherwise the parameter itself. Is it val = isRef (val)? Val.value: the syntax sugar function of val.

3.1 use examples

Const {ref, unref} = Vue const name = ref ("Brother Po") console.log (unref (name)) / / "Brother Po"

3.2 function implementation

/ / packages/reactivity/src/ref.ts export function unref (ref: t): T extends Ref? V: t {return isRef (ref)? (ref.value as any): ref}

Inside the unref function, the isRef function determines whether the ref parameter is a ref object, and if so, the value of ref.value is returned, otherwise the parameter itself is returned.

IV. ToRef

This function can be used to create a new ref for a property on a source responsive object. After that, the ref can be passed and it maintains a responsive connection to its source property.

4.1 examples of use

Const {reactive, toRef} = Vue const man = reactive ({name: "Po Brother", skill: "Vue 3"}) const skillRef = toRef (man, 'skill'); console.log (`skillRef.value:$ {skillRef.value} `); / / skillRef.value:Vue 3 skillRef.value = "Vite 2"; console.log (`man.skill:$ {man.skill}`); / / man.skill:Vite 2

4.2 function implementation

/ / packages/reactivity/src/ref.ts export function toRef (object: t, key: K): ToRef {return isRef (objectkey)? Object [key]: (new ObjectRefImpl (object, key) as any)}

The toRef function accepts two parameters, object and key, where the type of the object parameter is not primitive. In the function, it determines whether the object [key] object is a ref object, and if so, directly returns the value of object [key], otherwise it calls the constructor of the ObjectRefImpl class and returns an instance of the class:

/ / packages/reactivity/src/ref.ts class ObjectRefImpl {public readonly _ v_isRef = true / / used to identify the ref object constructor (private readonly _ object: t, private readonly _ key: K) {} get value () {return this._ object [this. _ key]} set value (newVal) {this._ object [this. _ key] = newVal}}

The definition of the ObjectRefImpl class is simple, and it contains a public read-only property, _ _ v_isRef, that identifies whether an instance of the class is a ref object. In addition, a setter and getter methods are included to manipulate the value of value.

5. ToRefs

This function is used to convert a responsive object into a normal object, where each property of the resulting object is a ref that points to the corresponding property of the original object.

5.1 examples of use

Const {reactive, toRefs} = Vue const man = reactive ({name: "Po Brother", skill: "Vue 3"}) console.log (toRefs (man))

5.2 function implementation

/ / packages/reactivity/src/ref.ts export function toRefs (object: t): ToRefs {if (_ _ DEV__ & &! isProxy (object)) {console.warn (`toRefs () expects a reactive object but received a plain one.`)} const ret: any = isArray (object)? New Array (object.length): {} for (const key in object) {ret [key] = toRef (object, key) / / call the toRef function to create a new ref} return ret} for the object's property

As can be seen from the above code, toRefs is mainly used to convert responsive objects into normal objects, and each property of the object is handled by calling the toRef function during the conversion process. It is important to note that the toRefs function generates ref for the property contained in the source object. If you want to create a ref for a specific property, you should use the toRef function.

When the code for the toRefs sample executes successfully, the console outputs the following result:

So what is the use of the toRefs function in a real project? ToRefs is useful when returning a responsive object from the setup function so that the component can deconstruct the returned object without losing responsiveness:

Const {reactive, toRefs, createApp} = Vue function useLoginInfo () {const man = reactive ({name: "Po Brother", skill: "Vue 3"}) / / convert to ref return toRefs (man)} const app = createApp ({setup () {/ / deconstruct const {name without losing responsiveness Skill} = useLoginInfo () return {name, skill}}, template: `{{name}} is learning {{skill}}`}) app.mount ("# app")

In the above example, we used the toRefs function inside the useLoginInfo function to transform responsive man objects. If the responsive man object is returned directly, the values of name and skill during deconstruction are shown in the following figure:

After converting the responsive object man through the toRefs function, the values of name and skill during deconstruction are as follows:

By comparison, it is found that after using the toRefs function, the deconstruction operation can be performed without losing responsiveness.

VI. ShallowRef

This function is used to create a ref that tracks changes in its .value, but does not make its value responsive.

6.1 examples of use

Const {shallowRef, isReactive} = Vue const shallowMan = shallowRef ({name: "Po Brother", skill: "Vue 3"}) console.log (isReactive (shallowMan.value)) / / false

6.2 function implementation

/ / packages/reactivity/src/ref.ts export function shallowRef (value: t): T extends Ref? T: Ref export function shallowRef (value: t): Ref export function shallowRef (): Ref export function shallowRef (value?: unknown) {return createRef (value, true)}

Within the shallowRef function, the ref object is also created by calling the createRef factory function. The difference from the ref function described earlier is that the second parameter of the createRef function is not set inside the ref function, and the default value of this parameter is false, as shown below:

Function createRef (rawValue: unknown, shallow = false) {if (isRef (rawValue)) {return rawValue} return new RefImpl (rawValue, shallow)}

As you can see from the output of the shallowRef example, if the value of the shallow parameter is true, the shallowMan.value object is not responsive. To further understand the difference between the shallowRef function and the ref function, we need to analyze the concrete implementation of the RefImpl class:

/ / packages/reactivity/src/ref.ts class RefImpl {private _ value: T public readonly _ v_isRef = true / / used to determine whether it is a ref object constructor (private _ rawValue: t, public readonly _ shallow = false) {this._value = _ shallow? _ rawValue: convert (_ rawValue) / / whether to convert a _ rawValue object into a responsive object} get value () {track (toRaw (this), TrackOpTypes.GET) 'value') / / track get operation return this._value} set value (newVal) {if (hasChanged (toRaw (newVal), this._rawValue)) {/ / determine whether the value has changed this._rawValue = newVal this._value = this._shallow? NewVal: convert (newVal) trigger (toRaw (this), TriggerOpTypes.SET, 'value', newVal) / / trigger set operation}

In the RefImpl constructor, if the value of _ shallow is true, the value of _ rawValue will be directly assigned to the this._value attribute, otherwise the convert function will be called to convert the value of _ rawValue before the assignment operation. The convert function is defined in the reactivity/src/ref.ts file:

/ / packages/reactivity/src/ref.ts const convert = (val: t): t = > isObject (val)? Reactive (val): val

If the value to be converted is an object type, the val object is converted to a responsive object using the reactive function, otherwise the val object is returned without doing any processing.

After learning about the shallowRef function, you may wonder what the impact of using the shallowRef function will be in a real project. Here, Brother Po, let me give you a specific example:

Const {shallowRef, watchEffect} = Vue const shallowMan = shallowRef ({name: "Po Brother", skill: "Vue 3"}) watchEffect (() = > {console.log (shallowMan.value.skill)}) shallowMan.value.skill = "Vite 2"

After the above code is executed, the console will output "Vue 3" only once, but the value of shallowMan.value has been updated:

ShallowMan.value {name: "Brother Po", skill: "Vite 2"}

So how to output the latest values in time? To solve this problem, you can use the triggerRef function.

7. TriggerRef

This function is used to manually perform any side effects associated with shallowRef.

7.1 examples of use

Const {shallowRef, watchEffect, triggerRef} = Vue const shallowMan = shallowRef ({name: "Po Brother", skill: "Vue 3"}) watchEffect (() = > {console.log (shallowMan.value.skill)}) shallowMan.value.skill = "Vite 2" triggerRef (shallowMan) / / manually perform any side effects associated with shallowMan

After adding the line triggerRef (shallowMan), and the above code runs successfully, the console will output the following:

Vue 3 Vite 2

7.2 function implementation

Export function triggerRef (ref: Ref) {trigger (toRaw (ref), TriggerOpTypes.SET, 'value', _ _ DEV__? Ref.value: void 0)}

Inside the triggerRef function, the trigger function exported in the effect.ts file is called to trigger the TriggerOpTypes.SET operation. Where TriggerOpTypes is an enumeration object that defines the type of operation that is triggered. In addition to SET, there are ADD, DELETE, CLEAR and other operations:

/ / packages/reactivity/src/operations.ts export const enum TriggerOpTypes {SET = 'set', ADD =' add', DELETE = 'delete', CLEAR =' clear'}

All right, let's stop here with the triggerRef function. As for how the trigger function works inside, Po will uncover the secret behind it in a later article. Finally, let's introduce the customRef function.

VIII. CustomRef

This function is used to create a custom ref and explicitly control its dependency tracking and update triggering. It requires a factory function that takes the track and trigger functions as arguments and returns an object with get and set.

8.1 example of use

Const {customRef, createApp} = Vue 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)} const app = createApp ({setup () {return {text: useDebouncedRef ('Brother Po')}}, template: ``}) app.mount ("# app")

In the above example, we used the customRef function to create a custom ref that provides debounce functionality.

8.2 function implementation

/ / packages/reactivity/src/ref.ts export function customRef (factory: CustomRefFactory): Ref {return new CustomRefImpl (factory) as any}

The customRef function accepts a factory parameter of type CustomRefFactory:

/ / packages/reactivity/src/ref.ts export type CustomRefFactory = (track: () = > void, trigger: () = > void) = > {get: () = > T set: (value: t) = > void}

As you can see from the above type definition, the custom ref factory function takes the track and trigger functions as arguments and returns an object with get and set. Inside the customRef function, the constructor of the CustomRefImpl class is called with the incoming factory factory function as an argument and the newly created instance is returned.

The CustomRefImpl class is defined in the reactivity/src/ref.ts file, and the implementation is as follows:

/ / packages/reactivity/src/ref.ts class CustomRefImpl {private readonly _ get: ReturnType ['get'] private readonly _ set: ReturnType [' set'] public readonly _ v_isRef = true / / used to identify ref object constructor (factory: CustomRefFactory) {const {get, set} = factory (() = > track (this, TrackOpTypes.GET, 'value'), / / track get operation () = > trigger (this, TriggerOpTypes.SET) 'value') / / trigger set operation) this._get = get this._set = set} get value () {return this._get ()} set value (newVal) {this._set (newVal)}}

In the constructor of the CustomRefImpl class, the incoming factory factory function is called and then the object returned by the factory function is deconstructed. Taking the previous customRef example as an example, the functions corresponding to get and set are as follows:

CustomRef ((track, trigger) = > {return {get () {track () / () = > track (this, TrackOpTypes.GET, 'value') return value}, set (newValue) {clearTimeout (timeout) timeout = setTimeout (() = > {value = newValue trigger () / / () = > trigger (this, TriggerOpTypes.SET,' value')} Delay)}) this is what the editor shares with you about the advance of Vue 3.0. what is a responsive Refs API? If you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report