Composite API
setup
-
The timing of setup execution
- Executed once before beforeCreate, this is undefined.
-
parameter of setup
- props: The value is an object, including: the properties passed from outside the component and received by the internal declaration of the component.
// 第一种情况 <script> export default { props: { num: Number }, setup(props) { console.log(props.num) return } } </script> // 第二种情况 <script setup> const props = defineProps({ num: Number }) console.log(props.num) </script>
-
context: context object
-
The context object is not reactive and can be safely destructured: { attrs, slots, emit, expose }
-
attrs: The value is an object, including: attributes passed from outside the component but not declared in the props configuration, equivalent to
this.$attrs
. -
slots: Received slot content, equivalent to
this.$slots
. -
emit: A function that dispatches custom events, equivalent to
this.$emit
.
// 模板 <template> <div> { {num}} <button @click="emit('change')">num++</button> </div> </template> // 第一种情况 <script> export default { emits: ['change'], props: { num: Number }, setup(p, context) { console.log(p, context.emit) return { emit: context.emit } } } </script> // 第二种情况 <script setup> const props = defineProps({ num: Number }) const emit = defineEmits(['change']) </script>
-
Responsive API
ref
- Role: Define a responsive data
- grammar:
const xxx = ref(initValue)
- Create a reference object (reference object, ref object for short) that contains responsive data .
- Data manipulation in JS:
xxx.value
- Read data in the template: No need for .value, directly:
<div>{ {xxx}}</div>
- Remark:
- The received data can be: basic type or object type.
- Basic types of data: Reactive is still dependable
Object.defineProperty()
andget
completeset
. - Object type data: internally "rescues" a new function in Vue3.0 -
reactive
function.
reactive
- Function: Define an object type of responsive data (do not use it for basic types, but use
ref
functions) - Syntax:
const 代理对象= reactive(源对象)
Receive an object (or array) and return a proxy object (the instance object of Proxy, referred to as proxy object) - The reactive data defined by reactive is "deep".
- The internal ES6-based Proxy implementation operates on the internal data of the source object through the proxy object.
shallowReactive与shallowRef
- shallowReactive: only handles the response (shallow response) of the outermost properties of the object.
- shallowRef: only handles the response of basic data types, not the response of objects.
readonly与shallowReadonly
- Takes an object (reactive or plain) or a ref and returns a readonly proxy
- readonly: Make a reactive data read-only (deep read-only).
- shallowReadonly: Make a responsive data read-only (shallow read-only).
import { reactive, readonly, watchEffect } from 'vue'
const original = reactive({ count: 0 })
const copy = readonly(original)
watchEffect(() => {
console.log(copy.count)
})
original.count++
copy.count++ // warning!
computed
import {computed} from 'vue'
setup(){
...
//计算属性——简写
let fullName = computed(()=>{
return person.firstName + '-' + person.lastName
})
//计算属性——完整
let fullName = computed({
get(){
return person.firstName + '-' + person.lastName
},
set(value){
const nameArr = value.split('-')
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
}
watch
-
Consistent with the watch configuration function in Vue2.x
-
Two small "pits":
- When monitoring the responsive data defined by reactive: oldValue cannot be obtained correctly, and deep monitoring is forcibly enabled (the deep configuration is invalid).
- When monitoring an attribute in the reactive data defined by reactive: the deep configuration is valid.
//情况一:监视ref定义的响应式数据
watch(sum,(newValue,oldValue)=>{
console.log(newValue,oldValue)
},{immediate:true})
//情况二:监视多个ref定义的响应式数据
watch([sum,msg],(newValue,oldValue)=>{
console.log(newValue,oldValue)
})
/* 情况三:监视reactive定义的响应式数据
若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!!
若watch监视的是reactive定义的响应式数据,则强制开启了深度监视
*/
watch(person,(newValue,oldValue)=>{
console.log(newValue,oldValue)
},{immediate:true,deep:false}) //此处的deep配置不再奏效
//情况四:监视reactive定义的响应式数据中的某个属性
watch(()=>person.job,(newValue,oldValue)=>{
console.log(newValue,oldValue)
},{immediate:true,deep:true})
//特殊情况
watch(()=>person.age,(newValue,oldValue)=>{
console.log(newValue,oldValue)
},{deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效
watchEffect
-
It is not necessary to specify which property to monitor, which property is used in the monitoring callback, then which property to monitor.
-
watchEffect is a bit like computed:
- But computed pays attention to the calculated value (the return value of the callback function), so the return value must be written.
- And watchEffect pays more attention to the process (the function body of the callback function), so there is no need to write the return value.
watchEffect(()=>{
const num1 = sum.value
const num2 = person.age
console.log('watchEffect')
})
toRef and toRefs
- When a property in the responsive object is provided for external use alone
const name = toRef(person,'name')
return {
...toRefs(obj),
msg
}
Checks API
- isRef: Checks whether a value is a ref object.
- unref: Returns the internal value if the argument is a ref, otherwise returns the argument itself. This is a sugar function (val = isRef(val) ? val.value : val)
- isProxy: Checks if the object is a proxy created by reactive, readonly, shallowReactive, shallowReadonly.
- isReactive: Check if the object is reactive, shallowReactive
- isReadonly: Check if the object is readonly, shallowReadonly
other
- Example: Create a debounced ref that only updates the value after some timeout from the most recent set call:
- The track method is placed in get to indicate that this data needs to track changes
- Vue reparses the template to trigger the event trigger, telling Vue to trigger the page update
<template>
<input type="text" v-model="keyword">
<h3>{
{keyword}}</h3>
</template>
<script>
import {ref,customRef} from 'vue'
export default {
name:'Demo',
setup(){
// let keyword = ref('hello')
function myRef(value,delay){
let timer
return customRef((track,trigger)=>{
return{
get(){
track()
return value
},
set(newValue){
clearTimeout(timer)
timer = setTimeout(()=>{
value = newValue
trigger()
},delay)
}
}
})
}
let keyword = myRef('hello',500)
return {
keyword
}
}
}
</script>
toRaw and markRaw
-
toRaw:
- Function: Convert a responsive object
reactive
generated by a bot into a normal object . - Usage scenario: It is used to read the common object corresponding to the responsive object. All operations on this common object will not cause page updates.
const foo = {} const reactiveFoo = reactive(foo) console.log(toRaw(reactiveFoo) === foo) // true
- Function: Convert a responsive object
-
markRaw:
- Role: Mark an object so that it will never become a responsive object again.
- Application scenario:
- Some values should not be set responsive, such as complex third-party libraries, etc.
- Skipping reactive transformations can improve performance when rendering large lists with immutable data sources.
const foo = markRaw({}) console.log(isReactive(reactive(foo))) // false // also works when nested inside other reactive objects const bar = reactive({ foo }) console.log(isReactive(bar.foo)) // false
life cycle
- The lifecycle hooks in Vue2.x can continue to be used in Vue3.0, but two of them have been renamed:
beforeDestroy
rename tobeforeUnmount
destroyed
rename tounmounted
- Vue3.0 also provides lifecycle hooks in the form of Composition API, and the corresponding relationship with the hooks in Vue2.x is as follows:
beforeCreate
===>setup()
created
=======>setup()
beforeMount
===>onBeforeMount
mounted
=======>onMounted
beforeUpdate
===>onBeforeUpdate
updated
=======>onUpdated
beforeUnmount
==>onBeforeUnmount
unmounted
=====>onUnmounted
Registers a hook to be called when an error propagated from a descendant component is caught.
- other life cycle
provide and inject
-
Role: Realize communication between ancestor and descendant components
-
Parent components have an
provide
option to provide data, and descendant components have aninject
option to start consuming that data
// 祖级
setup(){
const add=()=>{
num.value++
}
provide('add',add)
}
// 后代
setup(){
const add=inject('add')
return{
add
}
}
errorcaptured)
provide and inject
[External link image transfer...(img-28sDWGYu-1651830543792)]
-
Role: Realize communication between ancestor and descendant components
-
Parent components have an
provide
option to provide data, and descendant components have aninject
option to start consuming that data
// 祖级
setup(){
const add=()=>{
num.value++
}
provide('add',add)
}
// 后代
setup(){
const add=inject('add')
return{
add
}
}