Detailed explanation of vue3.0 composition API

Xia Mu and friends 2021-09-15 09:40:26

Preparation before creating a project

Before creating the project, you need to confirm whether vue The scaffold

Install scaffolding

npm install -g @vue/cli
 Copy code 

What's on it is Vue CLI3 edition

Create project

vue create Project name
 Copy code 

Creating steps

node Version in 10.0 above

1.png

2.png

3.png

4.png

5.png

6.png

7.png

8.png

9.png

10.png

11.png

It's worth noting Vue3 New characteristics

Composition API( Combine API)

composition-api What problems have been solved

Use traditional option There is a problem when configuring methods to write components , As business becomes more complex , The amount of code will continue to increase ; Because the relevant business code needs to follow option Write the configuration of to a specific area , The subsequent maintenance is very complicated , At the same time, the code reusability is not high , and composition-api It was created to solve this problem .

Composition API When using, you need to introduce

import { reactive, toRefs, computed } from "vue";
 Copy code 

1.setup yes composition-api The entry function of
2. In the declaration cycle beforeCreate Called before the event ;
3. You can return an object , The properties of this object are merged into the rendering context , And can be used directly in the template ;
receive props Object as first argument , Received props object , Can pass watchEffect Watch it change .
Accept context Object as the second parameter , This object contains attrs,slots,emit Three attributes . 4.context Replaced the this

because setup When executed , The component sample has not been created yet , So in setup There's no this. This means that in addition to props, You cannot use any other properties defined in the component , Include local status 、 Calculation properties and methods, etc .

setup(props, ctx) {
ctx.emit(' The ginseng ')
}
Of course , You can also emit It's more convenient to deconstruct it directly :
setup(props, { emit }) {
emit('ooxx')
}
 Copy code 

Grammar sugar Introduction

compositon-api The following functions are provided

  • ref
  • reactive
  • toRefs
  • computed
  • watch
  • watchEffect
  • Life cycle hooks

ref

Takes a parameter value and returns a responsive and changeable ref object

  1. ref Object has a single property that points to an internal value .value
  2. When ref When used in templates , He will automatically release , No need to write extra in the template .value
import { reactive, toRefs, computed } from "vue";
export default {
const count = ref(0)
const countAdd = ()=>{
count.value ++
}
return {
count
countAdd
}
}
 Copy code 

reactive

Receive a normal object and return the responsive proxy of the normal formation , Equate to 2.x Of Vue.observable() 1. Responsive conversion is “ Deep ”: It will affect all nested properties inside the object

import { reactive, toRefs, computed } from "vue";
export default {
const state = reactive({ count: 0,
double: computed(()=>state.count * 2)
})
return {
... toRefs(state)
double
}
}
 Copy code 
import { reactive, toRefs, computed } from "vue";
export default {
const state = reactive({ count: 0,
double: computed(()=>state.count * 2)
})
return toRefs(state)
}
 Copy code 

reactive and ref Choose between

Both are used to turn normal data into responsive data

1. When put ref() Created responsive data objects , Mount to reactive() Upper time , The responsive data object is automatically expanded to the original value , No need to pass .value Can be accessed directly
2.ref Add to reactive in , Use state.ref form , New incoming ref It will cover the original ref value , however ref and state yes Mutually independent ,state.ref Worth changing won't affect ref value , So the new incoming ref Cover the old ref, What is covered is just a pointer to the data .
3.ref For simple data types ,reactive For complex data types
4.ref stay return There is no need to deconstruct ,state stay return We need to deconstruct
5.ref Call the response data variable directly from the outside ,reactive When called, the normal data becomes
6. Data selection with strong correlation reactive, The code looks complete and tidy

toRefs

1.toRefs API Provides a way to put reactive The value of is treated as ref
2. take reactive The created responsive data object is transformed into a normal object , But every attribute node of this ordinary object is ref Type of responsive data , The extension operator... Is used here , Will state Change to normal object , So we need to use toRefs Turn it into responsive data .

import { reactive, toRefs, computed } from "vue";
export default {
setup() {
const state = reactive({ count: 0 })
const increment = () => { // Define the event handlers available on the page 
state.count++
}
// The return object can contain responsive data , You can also include event handlers 
return {
...toRefs(state),
increment
}
}
}
 Copy code 

Computed()

  • Create calculated properties , The return value is one ref example , So there is .value attribute
  • Import before use
  • Create a read-only calculated property :
export default {
setup(props, context) {
const tempData = ref(0);
const computeData = computed(() => {
tempData.value += 1; // Back to computeData It's also ref type 
})
console.log(tempData.value) //0
console.log(computeData.value) //1
}
}
 Copy code 
  • Create readable and writable calculation properties :
export default {
setup(props, context) {
const tempData = ref(0);
const computeData = computed({
get: () => {
tempData.value += 1;
},
set: (val) => {
tempData.value = val - 1;
}
})
console.log(tempData.value) //0
console.log(computeData.value) //1
computeData.value = 9;
console.log(tempData.value) //8
}
}
 Copy code 

watch(arg1,arg2,arg3)

  • Monitoring data changes , When created, it will automatically call , Sure adopt watch The third parameter of { lazy: true } close . The third parameter is used to configure listening parameters , for example immediately etc.
  • You need to import
  • Single data monitor :
export default {
setup(prop, context) {
//ref type 
const tempData = ref(0)
watch(
tempData,
(newVal, oldVal) => {
console.log(newVal);
},
{
lazy: true
}
)
//reactive type 
const tempData1 =reactive({count: 0})
watch(
()=>tempData1.count,
(newVal, oldVal) => {
console.log(newVal);
},
{
lazy: true
}
)
}
}
 Copy code 
  • Monitor multiple data changes
export default {
setup() {
//ref type 
const count = ref(0)
const name = ref('jack')
watch(
[count, name],
([newcount, newname], [oldcount, oldname]) => {
console.log(newcount, oldcount);
},
{
lazy: true
}
)
setTimeout(() => {
count.value++
name.value = 'lc'
}, 1000)
//reactive type 
const state = reactive({
count: 0,
name : 'jack'
})
watch(
[()=>state.count, ()=>state.name], // Listening data group 
([newcount, newname], [oldcount, oldname]) => { // Callback function 
console.log(newVal);
},
{
lazy: true
}
)
setTimeout(() => {
state.count++
state.name = 'lc'
}, 1000)
}
}
 Copy code 
  • Clear listening
// call watch The return value of , Once executed, it will clear .
const stop = watch(...)
stop() // Clear listening 
 Copy code 
  • Clear asynchronous invalid tasks

         This cleanup function will be called in the following cases :

watch It's repeated

watch Forced  stop  了

export default {
setup() {
const count = ref(0)
// Declare listening 
const stop = watch(
count,
(newVal, oldVal, onClear) => {
const timeId = asyncPrint(newVal) // Call asynchronous methods 
onClear(() => { // Repeated listening will delete the previous operation 
clearTimeout(timeId)
})
},
{lazy: true}
)
// Asynchronous methods 
const asyncPrint = (val) => {
return setTimeout(() => {
console.log(val)
},3000)
}
}
}
 Copy code 

watchEffect

watchEffect We collect dependencies at the beginning , comparison watch It can control whether to listen immediately during initialization ,watchEffect At the beginning, you have to do it again , Used to collect dependencies , Therefore watchEffect Don't like watch Then there will be the first parameter to specify the dependency , But in watchEffect In order to trigger listening, there must be responsive data to be monitored , If you change outside ref1, And in the watchEffect in console.log(ref2) It doesn't work , however watch It works

import { watchEffect } from 'vue'
const state1 = reactive({name: 'jack'})
setTimeout(() => {
state1.name = 'lc'
},8000)
watchEffect(() => {
console.log(state1.name) // Can't monitor 
})
 Copy code 
  • vue3.0 in , If watch Is an array object , that push Method does not trigger listening , The array must be re assigned to trigger .

provide

  • Data transfer between nested components can be realized ,  Use... In parent components  provide()  Function to pass data to subcomponents
  • No hierarchy , As long as it is a nested child component
  • stay setup() Use in
  • It needs to be introduced first
  • Share common data
export default {
setup() {
provide('globalColor','red')
}
}
 Copy code 
  • share ref Responsive data
export default {
setup() {
const color = ref('red')
provide('globalColor', color)
}
}
 Copy code 

inject

  • Data transfer between nested components can be realized ,  Use... In child components  inject()  Function to receive data from the parent component
  • No hierarchy , As long as it is its parent component ,
  • stay setup() Use in
  • It needs to be introduced first
  • Receive parameters from the parent
export default {
setup() {
inject('globalColor')
}
}
 Copy code 

template—refs

  • adopt ref() Realize the page DOM References and operations of elements and components
  • The parent component can manipulate the child component , Can get the data of sub components
  • example
<template>
<h3 ref='h3ref'><h3/> // binding return Response object data <com-child ref='comChild'/> <template/> <script> export default { setup() { const h3ref = ref(null) // Definition ref, The value is null const comChild = ref(null) onMounted(()=>{ // h3ref.value Equivalent to a native DOM h3ref.value.style.color = 'red' }) // Can get the sub components DOM const showNumber = () => { console.log(comChild.value.count) } return { h3ref, comChild, showNumber } } } </script>  Copy code 

Life cycle

The life cycle is written in setup() in

It needs to be advanced import introduce

import { onBeforeMount, onMounted, reactive, watchEffect } from 'vue'
 Copy code 

Compare the old life cycle with the new life cycle :

 beforeCreate --- setup()
created --- setup()
beforeMount --- onBeforeMount(()=>{…})
mounted --- onMounted(()=>{…})
beforeUpdate --- onBeforeUpdate(()=>{…})
updated --- onUpdated(()=>{…})
beforeDestroy --- onBeforeUnmount(()=>{…})
destroyed --- onUnmounted(()=>{…})
errorCaptured --- onErrorCaptured(()=>{…})
 Copy code 
Please bring the original link to reprint ,thank
Similar articles

2021-09-15