类组件支持几乎全部 Vuejs 原生生命周期钩子函数,钩子函数在类组件中同样使用类方法来表示,也就是说钩子函数是一组特殊的类方法。
内置钩子函数
钩子函数 | 执行时机 |
---|---|
beforeCreate | 在组件实例初始化完成之后立即调用 |
created | 在组件实例处理完所有与状态相关的选项后调用 |
beforeMount | 在组件被挂载之前调用 |
mounted | 在组件被挂载之后调用 |
beforeUpdate | 在组件即将因为一个响应式状态变更而更新其 DOM 树之前调用 |
updated | 在组件因为一个响应式状态变更而更新其 DOM 树之后调用 |
activated | 若组件实例是 [<KeepAlive>](https://cn.vuejs.org/api/built-in-components.html#keepalive) 缓存树的一部分,当组件被插入到 DOM 中时调用。 |
deactivated | 若组件实例是 [<KeepAlive>](https://cn.vuejs.org/api/built-in-components.html#keepalive) 缓存树的一部分,,当组件从 DOM 中被移除时调用 |
beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用。 |
beforeUnmount | 在一个组件实例被卸载之前调用 |
destroyed | 实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。 |
unmounted | 在一个组件实例被卸载之后调用 |
renderTracked | 在一个响应式依赖被组件的渲染作用追踪后调用(仅在开发模式下可用) |
renderTriggered | 在一个响应式依赖被组件触发了重新渲染之后调用(仅在开发模式下可用) |
serverPrefetch | 当组件实例在服务器上被渲染之前要完成的异步函数 |
render |
通过在 App 组件中动态切换组件来观察组件钩子函数的打印情况。
vue
<script lang="ts">
import { Component, Vue } from 'vue-facing-decorator';
@Component({
name: 'MyComponent',
})
export default class MyComponent extends Vue{
beforeCreate(){
console.log('beforeCreate 组件初始化完成')
}
created() {
console.log('created 组件实例状态初始化完毕')
}
beforeMount(){
console.log('beforeMount 组件开始被挂载')
}
mounted(){
console.log('mounted 组件被挂载完毕')
}
beforeUnmount(){
console.log('beforeUnmount 实例开始被卸载')
}
unmounted(){
console.log('unmounted 实例被卸载完毕')
}
}
</script>
<template>
<div>Hello World</div>
</template>
vue
<script lang="ts">
import MyComponent from './components/MyComponent.vue';
import {Component, Vue} from 'vue-facing-decorator';
@Component({
name: 'App',
components: {
MyComponent,
}
})
export default class App extends Vue {
isLoading = false;
changeStatus() {
this.isLoading = !this.isLoading;
}
}
</script>
<template>
<button @click="changeStatus">{{ isLoading ? '卸载组件' : '加载组件'}}</button>
<MyComponent v-if="isLoading">
</template>
下面是引用自 Vuejs 网站的组件的生命周期图:
其它钩子函数
除内置的钩子提供直接使用以外,往往在使用 Vuejs 全家桶其他的模块时,也会需要用到各种各种的钩子函数,这个时候就需要用到一个新的装饰器:@Hook
,通过 @Hook
装饰器来描述对应的方法是一个钩子函数。
配置组件及 router
对象:
typescript
import { createApp } from 'vue';
import './style.css';
import App from './App.vue';
import * as VueRouter from 'vue-router';
const routes = [
{ path: '/', component: () => import('./components/Home.vue') },
{ path: '/about', component: () => import('./components/About.vue') },
];
const router = VueRouter.createRouter({
history: VueRouter.createWebHashHistory(),
routes,
});
createApp(App)
.use(router)
.mount('#app');
配置 App 模板:
vue
<template>
<div>
<p>
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
</p>
<router-view></router-view>
</div>
</template>
在 Home 组件中使用 router
相关钩子函数:
vue
<script lang="ts">
import {Component, Hook, Vue} from 'vue-facing-decorator'
@Component({
name: 'Home'
})
export default class Home extends Vue {
@Hook
beforeRouteEnter(to, from) {
console.log('在渲染该组件的对应路由被验证前调用')
}
@Hook
beforeRouteLeave(to, from) {
console.log('在导航离开渲染该组件的对应路由时调用')
}
}
</script>
<template>
Home
</template>