理解Vue2的生命周期钩子

简介: 从基础到实战,我们一环都不要少!

生命周期

每个Vue 实例在被创建时都要经过一系列的初始化过程一一例如,需要设置数据监听、编译横板、将实例挂载到DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

下图展示了 Vue 的生命周期

image.png

vue 生命周期分为4个阶段,8个生命周期函数

  1. 创建阶段
  • beforeCreate

  • created ⭐

生命周期函数 created 里可以做数据初始化,比如说通过 Ajax 请求后端接口,请求成功后,把后端返回的数据保存到 data 上

不断更新页面时间

关键 我们知道,methods中自定义的函数方法,并不会自动执行,而生命周期函数是可以自动执行的

代码示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="vue.js"></script>
</head>

<body>
    <div id="app">
        <h1>{
  
  { time }}</h1>
    </div>
    <script>
        let app = new Vue({
    
    
            el: "#app",
            data: {
    
    
                time: new Date()
            },
            created() {
    
    
                setInterval(() => {
    
    
                    this.time = new Date()
                }, 1000)
            }
        })
    </script>
</body>

</html>
  1. 加载阶段
  • beforeMount

  • mounted ⭐⭐⭐

同样可以做数据初始化,还有某些需要用到页面元素的情况(因为此时页面已经渲染完成)

promise 封装 Ajax请求,在mounted函数中处理数据

代码示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="vue.js"></script>
</head>

<body>
    <div id="app">
        <h1>{
  
  { time }}</h1>

        <ul>
            <li v-for="item in foods">
                {
  
  { item.title }}-{
  
  { item.price }}
            </li>
        </ul>
    </div>
    <script>
        let app = new Vue({
    
    
            el: "#app",
            data: {
    
    
                time: new Date(),
                url: "https://www.fastmock.site/mock/f7051d6cb026fc0f2f55f086b5e96dc6/api/food",
                foods: []
            },
            mounted() {
    
    
                // 调用接口 亲求数据
                this.getDate(this.url).then((result) => {
    
    
                    // 数据请求成功后 保存到data上
                    this.foods = JSON.parse(result)
                }).catch((err) => {
    
    
                    console.log(err)
                })
            },
            methods: {
    
    
                getDate(url) {
    
    
                    return new Promise((resolve, reject) => {
    
    
                        let xhr = new XMLHttpRequest()
                        xhr.open("GET", url)
                        xhr.send(null)
                        xhr.onreadystatechange = function () {
    
    
                            if (xhr.readyState === 4 && xhr.status === 200) {
    
    
                                resolve(xhr.responseText)
                            } else {
    
    
                            }
                        }
                    })
                }
            }
        })
    </script>
</body>

</html>
  1. 更新阶段
  • beforeUpdate

  • updated

  1. 实例销毁,卸载阶段
  • beforeDestroy ⭐

可以用来做一些清除定时器的操作

代码示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="vue.js"></script>
</head>

<body>
    <div id="app">
        <h1>{
  
  { time }}</h1>
    </div>
    <script>
        let app = new Vue({
    
    
            el: "#app",
            data: {
    
    
                time: new Date()
            },
            created() {
    
    
              this.timer = setInterval(() => {
    
    
                    console.log("实例销毁,但我仍在执行!!!!")
                    this.time = new Date()
                }, 1000)
            },
            beforeDestroy() {
    
    
                clearInterval(this.timer)
            }
        })
    </script>
</body>

</html>

该示例中,我们在控制台 app.$destory` 销毁实例后,发现生命周期函数中的定时器仍然在执行,所以可以在钩`beforeDestroy`中清除掉定时器,也即我们在控制台 `app.$destory 销毁实例后,定时器就在销毁前就停掉了

  • destroyed

完整代码示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="vue.js"></script>
</head>

<body>
    <div id="app">
        <h1 id="h1">{
  
  {count}}</h1>
    </div>
    <script>
        let app = new Vue({
    
    
            el: "#app",
            data: {
    
    
                count: 0
            },
            /*第一阶段:创建阶段*/
            /*数据初始化阶段*/
            beforeCreate() {
    
    
                console.group("=======beforeCreate=======");
                console.log(this.$el)
                console.log(this.count)
                console.groupEnd();
            },
            created() {
    
    
                console.group("=======created=======");
                console.log(this.$el)
                console.log(this.count)
                console.groupEnd();
            },
            /*数据初始阶段*/
            /*第一阶段:创建阶段结束*/
            /*第二阶段:加载阶段*/
            beforeMount() {
    
    
                console.group("=======created=======");
                console.log(this.$el)
                console.log(this.count)
                console.groupEnd();
            },
            mounted() {
    
    
                console.group("=======created=======");
                console.log(this.$el)
                console.log(this.count)
                console.groupEnd();
            },
            /*第二阶段:加载阶段结束*/

            // 阶段体会:
            // 通过打印发现,如果你想要拿到数据,对数据进行操作的话,至少要在 created 里面去做

            // 值得注意:
            // 一个实例创建,从开始到完成,它是只执行前4个生命周期函数钩子的
            // 那么这两个生命周期函数什么时候执行呢 ? 
            // 它是当数据发生变化的时候才会执行

            /*第三阶段: 更新阶段*/
            // beforeUpdate: 当数据变化后,视图更新前执行
            beforeUpdate() {
    
    
                console.group("=======beforeUpdate=======");
                console.log('count:', this.count)
                console.log('h1:', document.getElementById('h1').innerHTML)
                console.groupEnd();
            },
            // updated: 数据变化后,视图更新后执行
            updated() {
    
    
                console.group("=======updated=======");
                console.log('count:', this.count)
                console.log('h1:', document.getElementById('h1').innerHTML)
                console.groupEnd();
            },
            /*第三阶段: 更新阶段结束*/

            // 值得注意:
            // 默认是只执行前 4 个生命周期函数
            // 那什么时候才会执行这两生命周期函数呢 ?

            // 可以通过 app.$destroy() 触发
            /*第四阶段: 销毁阶段*/
            beforeDestroy() {
    
    
                console.group("=======updated=======");
                console.groupEnd();
            },
            destroyed() {
    
    
                console.group("=======updated=======");
                console.groupEnd();
            },
            /*第四阶段: 销毁阶段结束*/
        })
    </script>
</body>

</html>
---控制台操作---
17-life.html:23 =======beforeCreate=======
17-life.html:24 undefined
17-life.html:25 undefined
17-life.html:29 =======created=======
17-life.html:30 undefined
17-life.html:31 0
17-life.html:38 =======created=======
17-life.html:39 <div id="app">​…​</div>17-life.html:40 0
17-life.html:44 =======created=======
17-life.html:45 <div id="app">​…​</div>17-life.html:46 0
app.count = 2  // 更新
17-life.html:62 =======beforeUpdate=======
17-life.html:63 count: 2
17-life.html:64 h1: 0
17-life.html:69 =======updated=======
17-life.html:70 count: 2
17-life.html:71 h1: 2
app.$destroy() // 销毁
17-life.html:83 =======updated=======
17-life.html:87 =======updated=======
目录
相关文章
|
2月前
|
JavaScript
vue实例的data属性,可以在哪些生命周期中获取到
Vue实例的`data`属性在`beforeCreate`、`created`和`beforeMount`阶段已可访问。此时,虽能使用数据,但事件监听和DOM操作不可行。`beforeCreate`时数据可访问,但未初始化观测和事件;`created`时数据完全可用,但未挂载到DOM;`beforeMount`时仍可访问数据,DOM挂载未开始。
31 3
|
2月前
|
JavaScript API 开发者
vue3的生命周期
Vue3 保留了大部分 Vue2 的生命周期钩子,`同时引入了 Composition API`,为开发者提供了更灵活的逻辑复用和组织方式。以下是 Vue3 中组件生命周期的详细介绍
|
2月前
|
JavaScript
在vue中,在哪个生命周期内调用异步请求?
在vue中,在哪个生命周期内调用异步请求?
25 0
|
2月前
|
JavaScript
在vue中,Vue 的父组件和子组件生命周期钩子函数执行顺序?
在vue中,Vue 的父组件和子组件生命周期钩子函数执行顺序?
17 0
|
2月前
|
JavaScript
在vue中,谈谈你对 Vue 生命周期的理解?
在vue中,谈谈你对 Vue 生命周期的理解?
17 0
QGS
|
4月前
|
资源调度 JavaScript 前端开发
手拉手Vue3生命周期实战应用
手拉手Vue3生命周期实战应用
QGS
46 0
|
6天前
|
存储 JavaScript 前端开发
【Vue】绝了!这生命周期流程真...
【Vue】绝了!这生命周期流程真...
|
27天前
|
JavaScript 前端开发 测试技术
|
2月前
|
JavaScript
vue的实例生命周期?
vue的实例生命周期?
10 0
|
2月前
|
JavaScript 前端开发 API
【Vue】探究 Vue 2 与 Vue 3 生命周期:变化与延续
【Vue】探究 Vue 2 与 Vue 3 生命周期:变化与延续