Detailed explanation of Composition API in setup function in vue3

Disadvantages of Options API

First, let's talk about the disadvantages of Options API in vue2, and then the advantages of Composition API in vue3
In Vue2, we write components through the Options API:
A major feature of the Options API is to write the corresponding function module in the corresponding attribute;
For example, data defines data, methods defines methods, computed defines calculation attributes, and watch listens for attribute changes, including life
Periodic hook;
But this code has a big drawback:
When we implement a function, the code logic corresponding to the function will be split into various attributes;
When our components become larger and more complex, the list of logical concerns will grow, and the logic of the same function will be fragmented;
Especially for those who didn't write these components at first, the code of this component is difficult to read and understand (others who read the component);
Let's take a look at a very large component, in which the logical functions are divided by color:
The use of this fragmented code makes it extremely difficult to understand and maintain this complex component, and hides the potential logic problems;
And when we deal with a single logical concern, we need to constantly jump to the corresponding code block;


It would be better if we could collect the code related to the same logical concern.
This is what the Composition API wants to do and what it can help us accomplish.
Others call Vue composition API VCA for short

Understanding Composition API

Now that we know what the Composition API wants to help us do, let's take a look at how to do it?
In order to start using the Composition API, we need a place where we can actually use it (write code);
In the Vue component, this position is the setup function;
setup is actually another option of the component:
But this option is so powerful that we can use it to replace most of the other options written before;
For example, methods, computed, watch, data, life cycle, and so on;
Next, let's learn how to use this function:
Parameters of function
Return value of function

Parameters of setup function

Let's first study the parameters of a setup function, which mainly has two parameters:
First parameter: props
Second parameter: context
Props is very easy to understand. In fact, it means that the properties passed by the parent component will be put into the props object. If we need to use it in setup, we can
To get directly through props parameters:
For defining props types, we still use the same rules as before, and define them in props options;
And in the template, you can still use the properties in props normally, such as message;
If we want to use props in the setup function, we can't get it through this (I'll talk about why later);
Because props is directly passed to the setup function as a parameter, we can use it directly through parameters;
Another parameter is context, which we also call a SetupContext. It contains three attributes:
Attribs: all non prop attribute s;
Slots: slots passed from the parent component (this will be useful when returning with rendering function, which will be discussed later);
Emit: we will use emit when we need to issue events inside the component (because we can't access this, we can't issue events through this.$emit)
Writing method I

// No object structure
      message:{
            typeof:String,
            requier:true
      }
  },
setup(props,context){
      console.log(props.message);
      console.log(context.attrs.class);
      console.log(context.attrs.id);
      console.log(context.slots);
      console.log(context.emit);}

Writing method II

    // The object structure and position of the parameter cannot be changed. If props is not required, use, Instead, the latter uses deconstruction to write what you want
    setup(props,{attrs,slots,emit}){
      console.log(props.message);
      console.log(attrs.class);
      console.log(slots);
      console.log(emit);

Return value of setup function

Since setup is a function, it can also have a return value. What is its return value used for?
The return value of setup can be used in the template;
In other words, we can replace the data option with the return value of setup;
Even we can return an execution function instead of the method defined in methods:


However, if we operate counter in increment or increment, can we realize the responsiveness of the interface?
The answer is no;
This is because for a defined variable, by default, Vue will not track its changes to cause the responsive operation of the interface;

setup cannot use this

The behavior of this option is completely different from that of other setup() instances, because this option is not active in the internal setup() instance. This makes setup() confusing when used with other optional API s.
The meaning expressed is that this does not point to the current component instance; And before setup is called, data, computed, methods, etc. are not parsed;
Therefore, this cannot be obtained in setup;

Reactive API

If you want to provide responsive features for the data defined in setup, you can use the reactive function:

 setup(){
  //    The reactive API has restrictions on the types to be passed in. It requires us to pass in an object or array type: if we pass in a basic data type (String, Number, Boolean), we will report a warning
           let title=reactive({
               a:10
           });
           let c =ref(100)
           const foo = ()=>{
               title.a++
               console.log(title.a)        
       }

So what's the reason? Why can it become responsive?
This is because when we use the reactive function to process our data, dependency collection will be carried out when the data is used again;
When the data changes, all collected dependencies are carried out corresponding responsive operations (such as updating the interface);
In fact, the data option we write is also internally handed over to the reactive function to program the responsive object

Ref API

The reactive API has restrictions on the types passed in. It requires us to pass in an object or array type:
If we pass in a basic data type (String, Number, Boolean), we will report a warning;

At this time, Vue3 provides us with another API: ref API
Ref will return a variable responsive object, which maintains its internal value as a responsive reference, which is the source of ref name;
Its internal value is maintained in the value attribute of ref;

Here are two considerations:
When introducing the value of ref into the template, Vue will automatically help us unpack, so we don't need to use ref.value in the template
To use;
However, inside the setup function, it is still a ref reference, so we still need to use ref.value when operating it;

Ref automatic unpacking

Unpacking in the template is shallow unpacking. If our code is as follows:
If we put ref into a reactive attribute, it will be unpacked automatically when used in the template:

 <!-- Import in template ref When the value of, Vue It will automatically help us unpack, so we don't need to pass it in the template ref.value The way to use;-->
      <h1>{{c}}</h1>
 // ref object;
    let c =ref(100)
            
    //    However, inside the setup function, it is still a ref reference, so we still need to use ref.value when operating it
            const foo1 = ()=>{
                c.value++
            }
             return{
             c,
             foo1}
            ```
![Insert picture description here](https://img-blog.csdnimg.cn/e6e47ac4a5bd4609b5b06e850ed18537.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAemF5eW8=,size_20,color_FFFFFF,t_70,g_se,x_16)
![Insert picture description here](https://img-blog.csdnimg.cn/5fa9ce7968e8465792e97d0f58b3faa0.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAemF5eW8=,size_20,color_FFFFFF,t_70,g_se,x_16)
## Know readonly

We pass reactive perhaps ref You can get a responsive object, but in some cases, we pass it to other places (components)
Responsive objects want to be used in another place (component), but cannot be modified. How to prevent this from happening at this time?
pVue3 Provides us with readonly Methods of;
preadonly The read-only proxy that returns the native object (that is, it is still a Proxy,This is a proxy of set Method hijacked and not
 It can be modified);
n Common in development readonly Method passes in three types of parameters:
p Type 1: common object;
p Type II: reactive Returned object;
p Type III: ref Object of
![Insert picture description here](https://img-blog.csdnimg.cn/afbdca56ad5f492cbb82d10d9d28c45b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAemF5eW8=,size_20,color_FFFFFF,t_70,g_se,x_16)

## Use of readonly
**stay readonly There are the following rules during the use of:**
		readonly The returned objects are not allowed to be modified;
		But after readonly The original object processed is allowed to be modified;
			such as const info = readonly(obj),info Object cannot be modified;
			When obj When modified, readonly Returned info The object will also be modified;
			But we can't modify it readonly Returned object info;
		In fact, it's essentially readonly Of the returned object setter The method was hijacked;

## Application of readonly
 **So this readonly What's the use?**
When we pass data to other components, we often want other components to use the content we pass, but they can be used when they are not allowed to be modified
readonly It's too late;
![Insert picture description here](https://img-blog.csdnimg.cn/9c270509b2544b2e8c0f51b648f6628c.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAemF5eW8=,size_20,color_FFFFFF,t_70,g_se,x_16)
![Insert picture description here](https://img-blog.csdnimg.cn/1ed183cd6dc543cb976dda34696e6fa7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAemF5eW8=,size_15,color_FFFFFF,t_70,g_se,x_16)

## API for Reactive judgment

**isProxy**
	Check whether the object is created by reactive or readonly Created proxy. 
**isReactive**
	Check whether the object is created by reactive Create a responsive agent:	
	If the agent is readonly Built, but wrapped by reactive Another proxy created, it will also return true;
**isReadonly**	
	 Check whether the object is created by readonly Create a read-only proxy for.
**toRaw**
	 return reactive or readonly The original object of the proxy (persistent references to the original object are not recommended. Use with caution).
**shallowReactive**
	 Create a responsive agent that tracks itself property But does not perform deep responsive transformations of nested objects (Deep or native object). 
**shallowReadonly**
	 Create a proxy,Make its own property Is read-only, but does not perform deep read-only conversion of nested objects (deep is still readable and writable)

```javascript
 Insert code slice here

toRefs

The objects of toRefs and toRef must be responsive
If we use the deconstruction syntax of ES6 to deconstruct the object returned by reactive to obtain the value, then whether it is the variable after modifying the structure or the reactive
The returned state object and data are no longer responsive

So is there any way to make the properties we deconstruct be responsive?
Vue provides us with a function of toRefs, which can convert the attributes in the object returned by reactive into ref;
Then, the name and age that we construct again are ref;

This practice is equivalent to already in state If you modify a link between name.value, it will cause any change

toRef

If we only want to convert the attribute in a reactive object to ref, we can use the method of toRef:

ref other API s

unref
If we want to get the value in a ref reference, we can also use the unref method:
If the parameter is a ref, the internal value is returned; otherwise, the parameter itself is returned;
Is this Val = isref (VAL)? Val.value: the syntax function of Val;
isRef
Determine whether the value is a ref object.
shallowRef
Create a shallow ref object;
triggerRef
Manually trigger side effects associated with the shallowRef

customRef

Create a custom ref and display and control its dependency tracking and update trigger:
It requires a factory function that accepts track and trigger functions as parameters;
And should return an object with get and set;
Here we use a case:
Perform debounce (throttling) operation on bidirectional bound attributes

customRef case

app.vue

<template>
  <div class="app">
      <input v-model="message"/>
      <h2>{{message}}</h2>
  </div>
</template>

<script>
import debounceRef from './hook/useDebounceRef'
export default {
  setup(){
    const message = debounceRef("zayyo")
    return{
      message
    }
  }
 }
</script>

<style  scoped>

</style>

useDebounceRef.js

// Import customRef function
import {customRef} from 'vue';

// Custom ref
// The default value and delay (delay time) of the parameters passed in to the function is 1 second
export default function(value,delay=1000){
    // Defining timer defaults to null
    let timer = null;
    // By default, it returns two parameters: customRef, track and trigger
    return customRef((track,trigger) =>{
        return{
            // By default, it returns the gent function and the set function
            get(){
                track();
                // Get dependence
                return value
            },
            set(newValue){
                // Get the new value and clear the time when you continue to enter
                clearTimeout(timer);
                // Set delay
                timer = setTimeout(() => {
                    // Endow nature
                    value = newValue;
                    trigger();
                }, delay);
            }
        }
    })

}
```directory structure
![Insert picture description here](https://img-blog.csdnimg.cn/5b74ad7cd556404b93b45668407f0ce9.png)

## Know readonly
 We pass reactive perhaps ref You can get a responsive object, but in some cases, we pass it to other places (components)
Responsive objects want to be used in another place (component), but cannot be modified. How to prevent this from happening at this time?

	 1. Vue3 Provides us with readonly Methods of;
 	2. readonly The read-only proxy that returns the native object (that is, it is still a Proxy,This is a proxy of set Method hijacked and not
	It can be modified);

Common in development readonly Method passes in three types of parameters:
 	1. Type 1: common object;
	 2. Type II: reactive Returned object;
 	3. Type III: ref Object of;

## Use of readonly
**stay readonly There are the following rules during the use of:**
	readonly The returned objects are not allowed to be modified;
	But after readonly The original object processed is allowed to be modified;
		1,such as const info = readonly(obj),info Object cannot be modified;
		2,When obj When modified, readonly Returned info The object will also be modified;
		3,But we can't modify it readonly Returned object info;
 	In fact, it's essentially readonly Of the returned object setter The method was hijacked;

Tags: Javascript Front-end Vue Vue.js

Posted by rimedey on Fri, 06 May 2022 04:57:02 +0300