生命周期
Vue3 的生命周期大部分还是和 Vue2 一样,除了beforeCreate
和created
,这两个已经替换成setup
了。在 Vue3 中,需要哪个生命周期钩子也可以用哪个,使用时需要用import
从Vue
中进行导入。
这些钩子中都应该在setup
中编写
官方 API:https://v3.cn.vuejs.org/api/options-lifecycle-hooks.html
对于 mounted 这类生命周期 API 与 vue2 中使用是类似的,不过在 vue3 中新增了onRenderTracked
和onRenderTriggered
。这两种只能在开发环境中调试使用。
实例:
<template>
<div> {{ val }} </div>
<button @click="change">渲染</button>
</template>
<script setup lang="ts">
import { ref, reactive,
onMounted, onBeforeMount, onBeforeUpdate, onUpdated,
onBeforeUnmount, onUnmounted, onErrorCaptured, onRenderTracked, onRenderTriggered} from "vue";
let val = ref(1)
function change():void {
val.value = 1000
}
// 在 Dom 加载前触发
onBeforeMount(() => {
console.log('onBeforeMount')
})
// 在 Dom 加载完触发
onMounted(() => {
console.log('onMounted')
})
// 在页面更新前触发
onBeforeUpdate(() => {
console.log('onBeforeUpdate')
})
// 在页面更新完触发
onUpdated(() => {
console.log('onUpdated')
})
// 在组件销毁之前触发
onBeforeUnmount(() => {
console.log('onBeforeUnmount')
})
// 在组件销毁完成触发
onUnmounted(() => {
console.log('onUnmounted')
})
// 在每次渲染后收集响应式依赖
onRenderTracked((event) => {
console.log('onRenderTracked')
console.log(event)
})
// 在每次触发页面重新渲染时自动执行
onRenderTriggered(({key, target, type}) => {
console.log('onRenderTriggered')
console.log({key, target, type})
})
</script>
复制代码
效果:
在实例中可以看到,最初渲染中,onBeforeMount
> onRenderTracked
> onMounted
,然后修改 val 数值,页面重新渲染触发onRenderTriggered
> onBeforeUpdate
> onUpdated
。
最后父组件中移除组件时,触发beforeUnmount
> onUnmounted
provide 提供/inject 注入
当需要从父组件向子组件传递数据时,可以使用props
,但是如果组件之间深度嵌套,深层的子组件需要父组件的部分内容,此时如果沿着props
一层层传递,就会显得非常复杂(当然也可以使用)
在之前的《不习惯的Vue3起步一》 中曾经说到过 attrs,这也可以用来获取祖先组件的属性,如果需要的数据不多,也可以使用这种方式。
通过provide
和inject
的结合,无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。这特性有两部分:父组件有一个provide
选项来提供数据,子组件有一个inject
选项来使用这些数据。
首先准备一个父组件:
<template>
<son></son>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, provide, watch } from "vue";
import son from './son.vue'
let msg = ref('张三')
provide("msgToChild", msg)
watch(msg, (newval)=>{
console.log(msg.value)
})
</script>
复制代码
然后是子组件:
<template>
<h1> {{ msg }} 说:hello </h1>
<button @click="change">改变</button>
</template>
<script setup lang="ts">
import { ref,Ref, reactive, onMounted,useAttrs, inject } from "vue";
let msg = inject('msgToChild')
function change() {
(msg as unknown as Ref<string>).value = Math.random().toString()
}
</script>
复制代码
效果: 在子组件中 inject 获取到了父组件数据,并且子组件中修改,父组件数据也会watch
监听到修改
注意 :在上面的例子中,想要产生响应式改变,传递的数据需要ref
或者reactive
包裹。此外在子组件中获取到的 msg 类型其实是 unknown,所以需要将其通过 as 进行转换。
评论