生命周期函数父子组件16个钩子执行顺序

前景提要:

1.有一对父子组件

2.父子组件中均有8个钩子函数

3.观察执行顺序及逻辑

先上结论,想看过程的可以继续看下面

结论:

当页面初次渲染时:

        1.首先触发父组件的beforeCreate,created,beforeMount三个钩子

        2.触发子组件的beforeCreate,created,beforeMount,mounted四个钩子

        3.最后再触发父组件的挂载后mounted钩子

当页面更新时:

        1.触发了子组件的更新前后beforeUpdate,updated两个钩子

当页面进行销毁时:

        1.子组件进行销毁

                触发自身的销毁前后beforeUpdate,updated两个钩子

        2.父组件对子组件进行销毁时

                首先触发父组件的更新前钩子beforeUpdate

                然后触发子组件的销毁前后beforeDestroydestroyed两个钩子

                最后触发父组件的更新后updated钩子

知识点:

        1.beforeCreate钩子       

                此时data el还未初始化  data,methods都还没有出现

        2.created钩子       

                此时data中的数据项能拿到但是没有真实DOM,this.$data也可以拿到数据,methods也出现了

        3.beforeMount 钩子

                此时模板已经在内存中渲染好了,但还未渲染到页面

        4.mounted钩子

                此时将内存中渲染好的模板替换到浏览器中

        5. beforeUpdate钩子       

                虚拟DOM重新渲染和打补丁之前被调用,在此修改data不会触发重渲染  

        6.updated钩子        

                虚拟DOM重新渲染 和打补丁之后被调用,此时不要修改data,否则会一直触发

beforeUpdate、updated这两个生命周期,进入死循环

        7.beforeDestroy 钩子

                此时实例准备进入销毁阶段,data methods  指令都还可以正常使用

        8.destroyed 钩子

                此时实例已经销毁,data methods  指令都不能使用

注意点:

        全局变量的生命周期:生:页面加载时  死:页面关闭时

        局部变量的生命周期:生:函数调用时  死:函数调用完毕时

参考代码(vue)

父:

<template>
  <div>
    <h1>hello</h1>
    <MySon/>
    
  </div>
</template>

<script>

import MySon from './MySon.vue'
export default {
  components:{
    MySon
  },
   beforeCreate () {
    // 1. 创建前
    console.log("beforeCreate --- 实例初始化前  父")
    console.log(this.msg) // undefined
  },
  created () {
    // 2. 创建后=> 发送ajax请求
    console.log("created ---  实例初始化后   父")
    console.log(this.msg) // "我是变量"
  },
  beforeMount () {
    // 3. 挂载前
    console.log("beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前  父")
    console.log(document.getElementById("myUl")) // null
    // console.log(document.getElementById("myUl").children[1].innerHTML) // 报错
  },
  mounted () {
    // 4. 挂载后=> 操作dom
    console.log("mounted --- vue的虚拟DOM, 挂载到真实的网页上   父")
    // console.log(document.getElementById("myUl").children[1].innerHTML)
    console.log(document.querySelector('#myUl').children[1].innerText)
  },
  beforeUpdate () {
    // 5. 更新前
    console.log("beforeUpdate --- 数据更新, 页面更新前   父")
    // 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
    // console.log(document.getElementById("myUl").children[4].innerHTML) // 报错
  },
  updated () {
    // 6. 更新后
    console.log("updated --- 数据更新, 页面更新后   父")
    console.log(document.getElementById("myUl").children[4].innerHTML)
  },
  beforeDestroy () {
    // 7. 销毁前
     // (清除定时器 / 解绑js定义的事件)
    console.log("beforeDestroy --- 实例销毁之前调用   父")
    
  },
  destroyed () {
    // 8. 销毁后
    // (清除定时器 / 解绑js定义的事件)
    console.log("destroyed --- 销毁完成   父")
  },
}
</script>

<style>

</style>

子:

<template>
  <div>
    <ul id="myUl">
      <li v-for="(item, ind) in arr" :key="ind">{{ item }}</li>
    </ul>
    <button
      @click="arr.push(Math.random() * 10)"
    >
      增加一个元素
    </button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      msg: "我是变量",
      arr: [1, 2, 3, 4],
      isShow: true,
    }
  },
  beforeCreate () {
    // 1. 创建前
    console.log("beforeCreate --- 实例初始化前")
    console.log(this.msg) // undefined
  },
  created () {
    // 2. 创建后=> 发送ajax请求
    console.log("created ---  实例初始化后")
    console.log(this.msg) // "我是变量"
    // this.time = setInterval(() => 
    //   console.log(new Date), 1000)
  },
  beforeMount () {
    // 3. 挂载前
    console.log("beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前")
    console.log(document.getElementById("myUl")) // null
    // console.log(document.getElementById("myUl").children[1].innerHTML) // 报错
  },
  mounted () {
    // 4. 挂载后=> 操作dom
    console.log("mounted --- vue的虚拟DOM, 挂载到真实的网页上 ")
    // console.log(document.getElementById("myUl").children[1].innerHTML)
    console.log(document.querySelector('#myUl').children[1].innerText)
  },
  beforeUpdate () {
    // 5. 更新前
    console.log("beforeUpdate --- 数据更新, 页面更新前")
    // 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
    // console.log(document.getElementById("myUl").children[4].innerHTML) // 报错
  },
  updated () {
    // 6. 更新后
    console.log("updated --- 数据更新, 页面更新后")
    console.log(document.getElementById("myUl").children[4].innerHTML)
  },
  beforeDestroy () {
    // 7. 销毁前
     // (清除定时器 / 解绑js定义的事件)
    console.log("beforeDestroy --- 实例销毁之前调用")
    
  },
  destroyed () {
    // 8. 销毁后
    // (清除定时器 / 解绑js定义的事件)
    console.log("destroyed --- 销毁完成")
    // clearInterval(this.time)
  },
};
</script>

<style>
</style>

直接看效果

 分析:

1.从这里可以看到在没有挂载到网页上之前数据是拿不到

2.父与子的执行顺序,初始渲染时先依次触发父组件的beforeCreate,created,beforeMount然后依次触发子组件的beforeCreate,created,beforeMount,mounted,最后再触发父组件的mounted

点击按钮更新页面,观察后续效果

分析: 

1.此处可以看到子组件的beforeUpdate,updated两个钩子触发了

2.此时的子组件获取到了数据

3.父组件的更新钩子没有触发

问题:

        那么销毁的钩子怎么触发呢?

       就是字面意思销毁,那么怎么触发呢?

//在子组件的ul上添加  v-if="isShow"

<ul id="myUl" v-if="isShow">

//在子组件的data新增

isShow:true


//在父组件也进行相同操作

<MySon v-if="isShow"/>

data() {
    return {
      isShow:true
    }
  },

直接看效果

首先是对子组件进行操作

发现干掉它自己只能触发自身的beforeUpdate,updated

 然后对父组件进行操作

 发现依次触发了父组件的beforeUpdate,子组件的beforeDestroy和destroyed,然后又触发了父组件的updated

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值