vue生命周期详解

1,130 阅读3分钟
  1. vue的生命周期分为四个阶段,一共8个钩子函数。
  2. 创建、挂载、更新和销毁
    • 创建:
      • beforeCreate:初始化事件和生命周期之后,数据尚未注入到组件之前会触发该钩子函数,适合处理预处理操作
      • created
    • 挂载:
      • beforeMount:DOM元素的操作,避免挂载后重排,提升性能
      • mounted:只会执行一次,适合挂载数据请求操作,可以防止多次请求
    • 更新:
      • beforeUpdate:数据更新渲染前自动调用beforeUpdate
      • updated:数据更新渲染后调用updated
    • 销毁:
      • beforeDestroy:路由切换时,组件就会被销毁,会调用beforeDestroy
      • destroyed
  3. 下面我提供一个完整的例子演示这四个阶段,你可以复制下面的代码打开浏览器查看示例:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <title>生命周期函数</title>
</head>

<body>
    <div id="app">
        <h3>请打开控制台查看生命周期的执行</h3>
        <router-link to='/'>HOME</router-link>
        <router-link to='/login'>LOGIN</router-link>
        <router-link to='/register'>REGISTER</router-link>
        <router-view></router-view>
    </div>
    <script>
        const Home = {
            beforeCreate: function () {
                console.log('beforeCreate触发了。在组件初始化事件以及生命周期之后,在数据尚未注入之前会触发beforeCreate函数。')
            },
            created: function () {
                console.log('当前组件:', this.$data.componentName)
                console.log('created触发了。数据已经注入,可以访问data。this.$data.name:', this.$data.name)
            },
            beforeMount: function () {
                console.log('beforeMount触发了。内部/外部模板已经被编译,模板尚未挂载。')
            },
            mounted: function () {
                console.log('mounted触发了。模板已经被渲染完成。该函数只会被执行一次')
            },
            data: function () {
                return {
                    componentName: 'Home',
                    name: 'Vue'
                }
            },
            methods: {
                changeName: function () {
                    this.name = "vue.js"
                }
            },
            template:
                `<div>
                <h1>Hello, {{ name }}</h1>
                <button v-on:click="changeName">更新名字</button>
            </div>`,
            beforeUpdate: function () {
                console.log('beforeUpdate触发了,数据发生了变化,但是还没有被渲染')
                alert("点击确定后,视图发生改变。")
            },
            updated: function () {
                console.log('updated触发了,渲染完成,更新视图。')
            },
            beforeDestroy: function () {
                console.log("beforeDestroy函数触发了,路由被切换了,组件还未被销毁")
                alert('路由发生了改变,当前组件即将被销毁,点击确定后进行跳转')
            },
            destroyed: function () {
                console.log("destroyed函数触发了,路由被切换了,组件销毁完成")
            }
        }
        const Login = {
            beforeCreate: function () {
                console.log('beforeCreate触发了。在组件初始化事件以及生命周期之后,在数据尚未注入之前会触发beforeCreate函数。')
            },
            created: function () {
                console.log('当前组件:', this.$data.componentName)
                console.log('created触发了。数据已经注入。this.$data.login_msg', this.$data.login_msg)
            },
            beforeMount: function () {
                console.log('beforeMount触发了。内部/外部模板已经被编译,模板尚未挂载。')
            },
            mounted: function () {
                console.log('mounted触发了。模板已经被渲染完成。该函数只会被执行一次')
            },
            template:
                `<div>
                <h1>这里是登陆页面</h1>
                <p>组件私有数据login_msg:{{ login_msg }}</p>
            </div>`,
            data: function () {
                return {
                    componentName: 'Login',
                    login_msg: "welcome to login page"
                }
            },
            beforeDestroy: function () {
                console.log("beforeDestroy函数触发了,路由被切换了,组件还未被销毁")
                alert('路由发生了改变,当前组件即将被销毁,点击确定后进行跳转')
            },
            destroyed: function () {
                console.log("destroyed函数触发了,路由被切换了,组件销毁完成")
            }
        }
        const Register = {
            beforeCreate: function () {
                console.log('beforeCreate触发了。在组件初始化事件以及生命周期之后,在数据尚未注入之前会触发beforeCreate函数。')
            },
            created: function () {
                console.log('当前组件:', this.$data.componentName)
                console.log('created触发了。数据已经注入。this.$data.register_msg:', this.$data.register_msg)
            },
            beforeMount: function () {
                console.log('beforeMount触发了。内部/外部模板已经被编译,模板尚未挂载。')
            },
            mounted: function () {
                console.log('mounted触发了。模板已经被渲染完成。该函数只会被执行一次')
            },
            template:
                `<div>
                <h1>这里是注册页面</h1>
                <p>组件私有数据register_msg:{{ register_msg }}</p>
            </div>`,
            data: function () {
                return {
                    componentName: 'Register',
                    register_msg: "welcome to register page"
                }
            },
            beforeDestroy: function () {
                console.log("beforeDestroy函数触发了,路由被切换了,组件还未被销毁")
                alert('路由发生了改变,当前组件即将被销毁,点击确定后进行跳转')
            },
            destroyed: function () {
                console.log("destroyed函数触发了,路由被切换了,组件销毁完成")
            }
        }
        const routes = [
            {
                path: '/login',
                name: 'login',
                component: Login
            },
            {
                path: '/register',
                name: 'register',
                component: Register
            },
            {
                path: '/',
                name: 'home',
                component: Home
            }
        ]
        const router = new VueRouter({
            routes,
        })
        var app = new Vue({
            el: "#app",
            router,
        })
    </script>
</body>

</html>