Vue3 推出了Composition API的新特性,相信大家都已经学习过了,官方文档上的教程写的也很详细。
但是有些官方文档中没有提到,但在使用过程中会遇到的问题,让我来探究一下。
两种生命周期钩子
在Composition API中可以声明生命周期钩子函数,对于以前的选项式生命周期钩子,除了beforeCreate
和created
没有外,其它都有相对应的。
那么两种生命周期可以共存吗?如果可以的话,执行顺序是怎么样的呢?
示例:
import { onBeforeMount, onMounted } from 'vue'
export default {
setup() {
console.log('setup')
onBeforeMount(() => {
console.log('onBeforeMount')
})
onMounted(() => {
console.log('onMounted')
})
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted')
}
}
输出的结果为:
setup
beforeCreate
created
onBeforeMount
beforeMount
onMounted
mounted
所以,在setup
中onBeforeMount
和beforeMounted
分别先于beforeMount
和mounted
触发。对于onBeforeUpdate
,onUpdated
,onBeforeUnmount
,onUnmounted
,情况是一样的。
ref和DOM
ref
可以创建一个响应式的变量,比如:
<template>
<div @click="count++">{{count}}</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup(){
const count = ref(0)
return {
count
}
}
}
</script>
ref
也可以用来建立对DOM元素的引用,比如:
<template>
<div ref="content"></div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
setup(){
const content = ref(null)
onMounted(()=>{
console.log(content.value) // <div></div>
})
return {
content
}
}
}
</script>
当setup
函数返回的变量中有和模板中ref
值相同的变量时,相对应的DOM引用会赋值到变量上。
初看这一点会让人有点迷惑,因为一般的用法是使用$refs
来获取DOM元素,但是ref
还有另一种函数声明方法:
<template>
<div ref="el => content = el"></div>
</template>
在Composition API中直接传递字符串应该是这种方式的语法糖。
引入组件
一般情况下,我们引入本地组件是这样的:
<template>
<c />
</template>
<script>
import C from 'c'
export default {
components:{
c: C
}
}
</script>
在Vue3.2的setup语法糖中,我们引入component的语句自动被转换为组件注册:
<template>
<c />
</template>
<script setup>
import C from 'c'
</script>
默认情况下,组件使用连字符命名方式。
那如果组件不是直接导出而是被包含在一个对象中呢?
比如:
<template>
<c />
</template>
<script>
import W from 'w'
export default {
components:{
c: W.C
}
}
</script>
此时只需要需要创建一个变量
<template>
<c />
</template>
<script setup>
import W from 'w'
const c = W.C
</script>
引入指令
引入的组件会被自动注册,那指令改如何注册呢?
与组件类似,引入的指令也会被自动注册,但是在名称上需要些许修改。
因为我们在使用指令时通常是v-x
的格式,所有我们在引入指令时,需要把名称改为vX
的格式:
<template>
<div v-x></div>
</template>
<script setup>
import {x as vX} from 'X'
</script>
异步setup
setup
方法可以是异步的吗?即:
async setup(){}
从实验结果来看,在一般的组件中,setup
方法不能是异步的。如果是异步函数,组件的初始化过程会中断。
但是在与suspense
配合的异步组件中可以使用异步的setup
方法。