Vue3 Composition-API
This article will briefly introduce the current Vue3 combined API The use and significance of .
Of course , When it's time to make fun of , Hey
1. Component state
With 2.x For example, the usage habits of , What we are most concerned about is the use of two-way data binding :
<template>
<button @click="increment">
Now it's : {{ state.count }}, Double is : {{ state.double }}
</button>
</template>
<script>
import {
computed,
reactive
} from 'vue'
export default {
setup() {
const state = reactive({
count: 1,
double: computed(() => state.count * 2)
})
function increment() {
state.count++;
}
return {
state,
increment
}
}
}
</script>
reactive
, Receives a normal object and returns the responsive proxy for that object , Equate to 2.x Medium Vue.observable()
;
Responsive conversion is “ Deep ”: Will affect all nested properties within the object . be based on Proxy The implementation of the , Returned proxy object It's not equal to The original object . We should try our best to use proxy objects and avoid relying on the original objects .
Vue
The essence of responsive systems : When in a component from data() Return an object ,, The internal is essentially by callingreactive()
Make it responsive .
computed
, Pass in a getter function , Returns a non manually modifiable ref object ;
computed Another way to use , Pass in a with get and set Function object of , Create a calculation state that can be manually modified ;
const double = computed({
get: () => count.value,
set: (val) => {
count.value = val * 2
}
})
watchEffect
For those used in the execution process Responsive state As rely on
Tracking ( And 2.x Medium watch The options are similar to , But it doesn't need to separate dependent data sources from side-effect callbacks ), And rerun the function when the dependency changes . When the components setup()
perhaps Lifecycle hook
When called ,watchEffect Will be linked to the lifecycle of the component , And in the components uninstall when Auto stop
.
new ref
, Takes a parameter value and returns a responsive and changeable ref object .ref Object has a single property that points to an internal value , namely .value
.
<template>
<button @click="increment">
The number goes up
</button>
<p>{{num}}</p>
</template>
<script>
import {
ref
} from 'vue'
export default {
setup() {
const num = ref(0);
function increment() {
num.value ++;
}
return {
increment,
num
}
}
}
</script>
If you pass in ref It's an object , Will call
reactive
Method for deep response conversion .
readonly
, Pass in an object or ref, Returns a read-only proxy of the original object . Even deep objects , Any internal properties are also read-only .
const original = reactive({count: 0});
const only = readonly(original);
watchEffect(() => { // Rely on tracking
console.log(only.count);
})
original.count ++; // The modification here will trigger only Monitoring of
only.count ++; // Unable to modify and warn
So far, the introduction has covered the pure state level of components : Responsive state 、 Calculate state and state changes when user input . Next, we will introduce the life cycle and Combinatorial API.
2. Lifecycle hook
import {
onMounted, onUpdated, onUnmounted
} from 'vue'
setup() {
//...
onMounted(() => {
console.log(' The component has been mounted !')
})
onUpdated(() => {
console.log(' The component has been updated !')
})
onUnmounted(() => {
console.log(' The component has been unloaded !')
})
//...
}
As shown in the example above , Lifecycle hook functions can only be registered in setup Function , Because they depend on the internal global state to locate the current component instance ( That is, calling setup() Component instance of ), Calling not under the current component throws an error .
The component instance context is set during the synchronization of lifecycle hooks , So the listener and computation state created synchronously when the component is unloaded will also be deleted .
In addition to the above example , And the hook :onBeforeMount、onBeforeUpdate、onBeforeUnmount、onErrorCaptured And new hooks onRenderTracked、onRenderTriggered.
3. combined API VS Optional API
Organized code ultimately makes code more readable , Easier to understand . What you see in the component is “ How to deal with this X、Y and Z”, Instead of “ This component has these data、 these property、 these methods”, That is to be more concerned about “ What is this component for ”. Options based API Naturally, the written code can't express the function of the component well .
The following is an example , When we use Optional API In development , It's very difficult to tease out the logic by reading the code in the options , Because the code related to logic is scattered everywhere . This fragmented development makes it very difficult to read and maintain later , The forced separation of options raises the threshold for logical understanding , We have to jump back and forth between blocks of code , To find the relevant code .
contrary , If you can put the same logic point code together , That would be the best thing . That's exactly what it is. combined API What to do . This pattern makes the logical point of the component become a good decoupling function : Each logical point code block is combined into a function , It greatly reduces the number of jumps back and forth . You can also fold these combinatorial functions , Easier to browse :
In addition to the extraction logic , Another change is this References to .
setup() Medium this And 2.x Medium this Completely different , At the same time setup() and 2.x Use in this It's going to cause chaos . Here we need to introduce setup Function :
- When creating a component instance , Initialize first props, It's followed by a call to setup function , And will be in beforeCreate Called before ;
- setup Return an object , The properties of the object will be merged into the context of the component template ;
- setup The first parameter of , Namely props;
- setup Second parameter of , Provides context objects , And from 2.x Some properties are exposed selectively in .
export default {
props: {
name: string,
age: number
},
setup(prop,context) {
watchEffect(() => {
console.log(`My name is ${props.name},I'm ${props.age} years old.`)
});
context.attrs
context.slots
context.emit
}
}
When extracting logical points , Logical methods can also receive parameters props and context:
const checkUsername = (props, context) => {
onMounted(() => {
console.log(props)
context.emit('event', 'payload')
})
}
export default {
setup (props, context) {
checkUsername(props, context)
}
}
4. Last
I hope this paper can help us understand Composition API How will we change the way we code , In the subsequent development activities , Improve the readability of the code , Improve cohesive coupling , After all, that's what a mature programmer needs to do .