Skip to content

Vue的生命周期

生命周期是什么

生命周期(Life Cycle)的概念应用很广泛,特别是在政治、经济、环境、技术、社会等诸多领域经常出现,其基本涵义可以通俗地理解为“从摇篮到坟墓”(Cradle-to-Grave) 的整个过程在 Vue 中实例从创建到销毁的过程就是生命周期,即指从创建、初始化数据、编译模板、挂载 Dom → 渲染、更新 → 渲染、卸载等一系列过程我们可以把组件比喻成工厂里面的一条流水线,每个工人(生命周期)站在各自的岗位,当任务流转到工人身边的时候,工人就开始工作

PS:在 Vue2 生命周期钩子会自动绑定 this 上下文到实例中,因此你可以访问数据,对 property 和方法进行运算这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos())

生命周期有哪些

Vue 生命周期总共可以分为这几个阶段:创建前后, 载入前后,更新前后,销毁前销毁后,以及一些特殊场景的生命周期

正常生命周期描述vue2vue3备注
setup组件实例被创建时没有新增setup是 Vue3 新增的生命周期钩子,
它可以代替beforeCreatecreated
beforeCreate组件实例被创建之初更改Vue3 中如果用组合式 API 则无法调用该钩子函数,
但是如果使用组合式则可以调用
created组件实例已经完全创建更改同上
beforeMount组件挂载之前未改变
mounted组件挂载到实例上去之后未改变
beforeUpdate组件数据发生变化,更新之前未改变
updated组件数据更新之后未改变
beforeDestroy组件实例销毁(卸载)之前更改vue3该生命周期的钩子函数还存在,
但是改名为beforeUnmount
destroyed组件实例销毁(卸载)之后更改vue3该生命周期的钩子函数还存在,
但是改名为unmounted
缓存生命周期描述vue2vue3备注
activatedkeep-alive 缓存的组件激活(重新进入)时
deactivatedkeep-alive 缓存的组件停用(再次离开)时
其他生命周期描述vue2vue3备注
errorCaptured捕获一个来自后代组件的错误时被调用2.5.0+
renderTracked调试钩子,当组件渲染过程中追踪到响应式依赖时调用
仅在开发模式下可用,且在服务器端渲染期间不会被调用
没有
renderTriggered调试钩子,当响应式依赖的变更触发了组件渲染时调用
仅在开发模式下可用,且在服务器端渲染期间不会被调用
没有
serverPrefetch异步函数,在组件实例在服务器上被渲染之前调用,仅在 SSR 可用没有

生命周期整体流程图

各生命周期中组件与数据的加载状态

我们以 Vue3 为例,创建一对父子组件:

vue
<template>
    <div>
        <div>
            <button @click="visible = !visible">{{ !visible ? '打开' : '关闭' }}子组件</button>
        </div>
        <child v-if="visible"/>
    </div>
</template>

<script>
    import child from './child.vue';

    export default {
        name: 'parent',
        components: {
            child
        },
        data() {
            return {
                visible: false
            }
        }
    };
</script>
vue
<template>
    <div>
        <span>{{ testData }}</span>
        <button @click="updateData">修改值</button>
    </div>
</template>

<script>
    export default {
        name: 'child',
        data() {
            return {
                testData: '我是子页面'
            };
        },
        methods: {
            updateData() {
                this.testData = this.testData + '=';
            }
        },
        setup() {
            console.log('setup', /*this.$el, this.$data*/); // 如果放开注释会报错
        },
        beforeCreate() {
            console.log('beforeCreate', this.$el, this.$data);
        },
        created() {
            console.log('created', this.$el, this.$data);
        },
        beforeMount() {
            console.log('beforeMount', this.$el, this.$data);
        },
        mounted() {
            console.log('mounted', this.$el, this.$data);
        },
        beforeUpdate() {
            console.log('beforeUpdate', this.$el, this.$data);
        },
        updated() {
            console.log('updated', this.$el, this.$data);
        },
        beforeUnmount() {
            console.log('beforeUnmount', this.$el, this.$data);
        },
        unmounted() {
            console.log('unmounted', this.$el, this.$data);
        },
        activated() {
            console.log('activated', this.$el, this.$data);
        },
        deactivated() {
            console.log('deactivated', this.$el, this.$data);
        }
    };
</script>

你可以打开控制台,点击下面按钮查看日志:


  • 当打开子组件
console
setup
beforeCreate null ▶ Object { }
created null ▶ Proxy { <target>: {…}, <handler>: {…} }
beforeMount ▶ null ▶ Proxy { <target>: {…}, <handler>: {…} }
mounted ▶ <div id="child" data-v-d003c437="" data-v-8216dc0a=""> ▶ Proxy { <target>: {…}, <handler>: {…} }
  • 当更新子组件
console
beforeUpdate ▶ <div id="child" data-v-d003c437="" data-v-8216dc0a=""> ▶ Proxy { <target>: {…}, <handler>: {…} }
updated ▶ <div id="child" data-v-d003c437="" data-v-8216dc0a=""> ▶ Proxy { <target>: {…}, <handler>: {…} }
  • 当关闭子组件
console
beforeUnmount ▶ <div id="child" data-v-d003c437="" data-v-8216dc0a=""> ▶ Proxy { <target>: {…}, <handler>: {…} }
unmounted ▶ <div id="child" data-v-d003c437="" data-v-8216dc0a=""> ▶ Proxy { <target>: {…}, <handler>: {…} }

可见在 Vue3 中:

当生命周期为组件状态数据状态触发时机
setupundefinedundefined进入组件时
beforeCreatenull未加载组件开始创建
creatednull已加载组件创建之后
beforeMountnull已加载组件开始安装
mounted已加载已加载组件安装完毕
beforeUpdate已加载已加载仅当数据更新时
updated已加载已加载仅当数据更新时
beforeUnmount已加载已加载组件准备卸载前
unmounted已加载已加载组件卸载之后
activated未触发未触发仅当组件已被缓存,重新进入时
deactivated未触发未触发仅当组件已被缓存,再次退出时
注意 在 Vue2 中 beforeCreatecreatedbeforeMount不显示为null未加载,而是显示为undefined,其余没什么区别

结论

如果需要操作 DOM,我们应该在 mounted 中去进行,因为在此之前 DOM 没有挂载完

如果是请求数据,应该在 created 中或之后进行