Vue3全家桶 - Vue3 - 【7】生命周期

生命周期

  • Vue3官网-生命周期钩子函数
  • 每个Vue组件实例在创建时都需要经历一系列的初始化步骤,比如数据侦听、编译模板、挂载实例到DOM,以及在数据改变时更新DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。最常见的是createdmountedupdatedunmounted

一、组合式API

  • 组合式API:生命周期钩子函数【官网上面还有一些别的钩子函数】

  • 🔺 setup 说明:

    • setup的执行时机:
      • beforeCreated钩子之前,自动执行;
    • setup中的this指向谁:
      • undefined
  • 父组件:

    html 复制代码
    <script setup>
        import { ref, reactive, computed, onMounted } from 'vue'
    
        // TODO 导入组件
        import Vue1 from '@/components/23-生命周期/组合式API/1.vue'
    
        // TODO 声明变量
        let isShow = ref(false)
    
        onMounted(() => {});
    </script>
    
    <template>
        <h3>App组件</h3>
        <label>
            <input type="checkbox" v-model="isShow"> 是否显示子组件
        </label>
        <hr>
        <Vue1 subTitle="好好学习" v-if="isShow" />
    </template>
  • 子组件:

    html 复制代码
    <template>
        <h4 id="age">
        <i>年龄:{{ age }}</i>
        </h4>
        <button @click="age = 70">年龄改成70</button>
        <button @click="age = 30">年龄改成30</button>
    </template>
    
    <script setup>
        import { ref, reactive, computed, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from "vue";
        // TODO 父组件传递的数据
        let props = defineProps({
            subTitle: {
                type: String
            }
        })
    
        // TODO 声明响应式数据
        let age = ref(22);
    
        const showMessage = () => {
            console.log('函数 HELLO')
        }
    
        // TODO 生命周期钩子函数
        onBeforeMount(() => {})
    
        onMounted(() => {})
    
        onBeforeUpdate(() => {})
    
        onUpdated(() => {})
    
        onBeforeUnmount(() => {})
    
        onUnmounted(() => {});
    </script>

1.1 onBeforeMount

  • 组件视图 在浏览器 渲染之前 调用;

  • 可访问

    • 组件实例东西【数据源、函数、计算属性等】;
  • 不能访问

    • 组件视图中的DOM元素。
  • 示例展示:

    html 复制代码
    <template>
      <h4 id="age">
        <i>年龄:{{ age }}</i>
      </h4>
      <button @click="age = 70">年龄改成70</button>
      <button @click="age = 30">年龄改成30</button>
    </template>
    
    <script setup>
    import { ref, reactive, computed, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from "vue";
    // TODO 父组件传递的数据
      let props = defineProps({
        subTitle: {
          type: String
        }
      })
    
    // TODO 声明响应式数据
    let age = ref(22);
    
    const showMessage = () => {
      console.log('函数 HELLO')
    }
    
    // TODO 生命周期钩子函数
    onBeforeMount(() => {
      console.log('-----------------------')
      console.log('onBeforeMount - 组件渲染之前,能访问数据源、计算属性、侦听器、函数等等,但是不能访问DOM元素')
      console.log(age.value)
      console.log(props.subTitle)
      showMessage()
      console.log(document.getElementById("age"))
    })
    </script>
  • 运行效果:

1.2 onMounted

  • 组件视图 在浏览器 渲染之后 调用;

  • 可访问

    • 组件实例东西【数据眼、函数、计算属性等】;
    • 组件视图中的DOM元素。
  • 示例展示:

    js 复制代码
    onMounted(() => {
        console.log('-----------------------')
        console.log('onMounted - 组件视图渲染之后,能访问数据源、计算属性、侦听器、函数、DOM元素等等')
        console.log(age.value)
        console.log(props.subTitle)
        showMessage()
        console.log(document.getElementById("age"))
    })
  • 运行效果:

1.3 onbBeforeUpdate

  • 数据源发生变化 时,组件试图重新 渲染之前 调用;

  • 可访问

    • 组件实例的东西【数据源、函数、计算属性】;
  • 注意

    • 可访问 该组件中在 更新之前的DOM元素
    • 不能访问 该组件中在 更新之后的DOM元素
  • 示例展示:

    js 复制代码
    onBeforeUpdate(() => {
        console.log('-----------------------')
        console.log('onBeforeUpdate - 数据变化之前,能访问数据源、计算属性、侦听器、函数、视图重新渲染之前的DOM元素等等')
        console.log(age.value)
        console.log(props.subTitle)
        showMessage()
        console.log(document.getElementById("age").innerHTML)
    })
  • 运行效果:

1.4 onUpdated

  • 数据源发生变化 时,组件试图重新 渲染之后 调用;

  • 可访问

    • 组件实例东西【数据源、函数、计算属性等】;;
  • 注意

    • 不能访问 该组件中在 更新之前的DOM元素
    • 可以访问 该组件中在 更新之后的DOM元素
  • 示例展示:

    js 复制代码
    onUpdated(() => {
      console.log('-----------------------')
      console.log('onUpdated - 数据变化之后,能访问数据源、计算属性、侦听器、函数、视图重新渲染之后的DOM元素等等')
      console.log(age.value)
      console.log(props.subTitle)
      showMessage()
      console.log(document.getElementById("age").innerHTML)
    })
  • 运行效果:

1.5 onBeforeUnmount

  • 组件实例被 卸载之前 调用;

  • 可访问

    • 组件实例东西【数据源、函数、计算属性】;
    • 组件试图中的DOM元素。
  • 示例代码:

    js 复制代码
    onBeforeUnmount(() => {
      console.log('-----------------------')
      console.log('onBeforeUnmount - 组件卸载之前,能访问数据源、计算属性、侦听器、函数、视图DOM元素等等')
      console.log(age.value)
      console.log(props.subTitle)
      showMessage()
      console.log(document.getElementById("age"))
    })
  • 运行效果:

1.6 onUnmounted

  • 组件实例被 卸载之后 调用;

  • 可访问

    • 组件实例东西【数据源、函数、计算属性】;
  • 不能访问

    • 组件试图中的DOM元素;
  • 一般在这个生命周期函数里,我们可以手动清理一些副作用,例如计时器、DOM事件监听器或者与服务器的连接。

  • 示例代码:

    js 复制代码
    onUnmounted(() => {
      console.log('-----------------------')
      console.log('onUnmounted - 组件卸载之后,能访问数据源、计算属性、侦听器、函数等等,但是不能视图DOM元素')
      console.log(age.value)
      console.log(props.subTitle)
      showMessage()
      console.log(document.getElementById("age"))
    });
  • 运行效果:

二、 选项式API

2.1 beforeCreate

  • beforeCreate 选项式 生命周期函数;

  • 组件实例初始化之前调用props解析已解析、datacomputed等选项还未处理】;

  • 能访问

    • props数据
  • 不能访问

    • 组件的实例 this
    • 组件中的 data中的数据methods中的方法
    • 组件中的 视图 DOM 元素
    • 组件中的 计算属性 等;
  • 组合式API 中的 setup()钩子 会在 所有选项式API钩子 之前 调用

  • 示例展示:

    • App.vue

      html 复制代码
      <script setup>
          import { ref, reactive, computed, onMounted } from 'vue'
          // 组合式API 中,导入组件之后不用注册,直接使用即可
          import Vue1 from '@/components/23-生命周期/1.vue'
      onMounted(() => {});
      </script>
      
      <template>
          <h4>App组件</h4>
          <br>
          <Vue1></Vue1>
      </template>
    • 子组件:

      html 复制代码
      <script>
          export default {
              props: {
                  subtitle: {
                      default: '不能懈怠!!!'
                  }
              },
              // data 写箭头函数的时候,给 return 的对象 添加小括号
              data: () => ({
                  age: 22
              }),
              methods: {
                  showMessage() {
                      console.log('函数:beforeCreate')
                  }
              },
              /**
              * 组件实例化之前调用
              * 能访问:
              *    props中的数据
              * 不能访问:
              *    data中的数据、methods中的方法、计算属性、视图DOM元素、组件实例this
              */
              beforeCreate() {
                  console.log('beforeCreate, 组件实例化之前')
                  console.log('能够访问props', this.$props.subtitle)
                  console.log('不能访问 data中的数据、方法、计算属性等', this.age)
                  console.log('不能访问 视图元素', document.getElementById('day'))
                  this.showMessage()
              }
          }
      </script>
      
      <template>
          <h4 id="day">每天进步一点点</h4>
      </template>
  • 运行展示:


2.2 created

  • created 选项式 生命周期函数;

  • 组件实例化 成功后 调用

  • 可访问

    • 组件的 实例this
    • 组件中的 data中的数据函数
    • 组件中的 计算属性
    • 还有 自定义属性(props) 等;
  • 不能访问

    • 组件中的 视图DOM元素
  • 示例展示:

    • 子组件代码:

      js 复制代码
      ocmputed: {
          ageAdd() {
              retutn this.age++
          }
      },
      /**
      * 组件 实例化 成功 之后 调用
      * 能访问:
      *    data数据、methods方法、props数据、组件实例this、计算属性
      * 不能访问:
      *    视图 DOM 元素
      */
      created() {
        console.log('-------------------------------')
        console.log('created 组件 实例化 成功 之后 调用')
        console.log('能够访问props:', this.$props.subtitle)
        console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd)
        console.log('不能访问 视图元素:', document.getElementById('day'))
        this.showMessage()
      },
  • 运行展示:


2.3 beforeMount

  • 组件视图在浏览器 渲染之前 调用;

  • 可访问

    • 组件实例东西【数据源、函数、计算属性等】;
  • 不能访问

    • 组件视图中的DOM元素。
  • 示例展示:

    js 复制代码
    /**
     * 组件视图 渲染之前 调用
     * 能访问:
     *    data数据、methods方法、计算属性、组件实例this、props数据等
     * 不能访问:
     *    视图DOM元素
     */
    beforeMount() {
        console.log('-------------------------------')
        console.log('beforeMount 组件视图 渲染之前 调用')
        console.log('能够访问props:', this.$props.subtitle)
        console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd)
        this.showMessage()
        console.log('不能访问 视图元素:', document.getElementById('day'))
    }
  • 运行效果:


2.4 mounted

  • 组件视图在浏览器 渲染之后 调用;

  • 可访问

    • 组件实例东西【数据眼、函数、计算属性等】;
    • 组件视图中的DOM元素。
  • 示例展示:

    html 复制代码
    <script>
        /**
         * 组件视图 渲染之后 调用
         * 能访问:
         *    组件实例this、data数据、methods方法、计算属性、侦听器、视图DOM元素
         */
        mounted() {
            console.log('-------------------------------')
            console.log('mounted 组件视图 渲染之后 调用')
            console.log('能够访问props:', this.$props.subtitle)
            console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd)
            this.showMessage()
            console.log('能访问 视图元素:', document.getElementById('day'))
        },
    </script>
    
    <template>
      <h4 id="day">每天进步一点点</h4>
      <h5 id="age">{{ age }}</h5>
      <button @click="age = 23">数据源发生改变,视图更新之前</button>
      <button @click="age = 24">数据源发生改变,视图更新之后</button>
    </template>
  • 运行效果:

2.5 beforeUpdate

  • 数据源发生变化 时,组件试图重新 渲染之前 调用;
  • 可访问
    • 组件实例的东西【数据源、函数、计算属性】;
  • 注意
    • 可访问 该组件中在 更新之前的DOM元素
    • 不能访问 该组件中在 更新之后的DOM元素
  • 示例代码:看下一小节(8.6),放在一起做对比,效果更明显;

2.6 updated

  • 数据源发生变化 时,组件试图重新 渲染之后 调用;

  • 可访问

    • 组件实例东西【数据源、函数、计算属性等】;;
  • 注意

    • 不能访问 该组件中在 更新之前的DOM元素
    • 可以访问 该组件中在 更新之后的DOM元素
  • 示例代码:

    html 复制代码
    <script>
        export default {
            /**
            * 数据源发生改变,视图重新渲染之前 调用
            * 能访问:
            *    组件实例this、data数据、methods方法、计算属性、侦听器、数据更新之前的视图DOM元素
            * 不能访问:
            *    数据更新之后的DOM
            */
            beforeUpdate() {
                console.log('-------------------------------')
                console.log('beforeUpdate 数据源发生改变,视图重新渲染之前 调用')
                console.log('能够访问props:', this.$props.subtitle)
                console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd)
                this.showMessage()
                console.log('能访问:数据源发生改变,视图更新之前的DOM元素:', document.getElementById('age').innerHTML)
            },
            /**
            * 数据源发生改变,视图重新渲染之后
            * 能访问:
            *    组件实例this、data数据、methods方法、计算属性、侦听器、数据更新之后的视图DOM元素
            * 不能访问:
            *    数据更新之前的DOM元素
            */
            updated() {
                console.log('-------------------------------')
                console.log('updated 数据源发生改变,视图重新渲染之后 调用')
                console.log('能够访问props:', this.$props.subtitle)
                console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd)
                this.showMessage()
                console.log('能访问:数据源发生改变,视图更新之后的DOM元素:', document.getElementById('age').innerHTML)
            }
        }
    </script>
    
    <template>
        <h4 id="day">每天进步一点点</h4>
        <h5 id="age">{{ age }}</h5>
        <button @click="age = 23">数据源发生改变,视图更新之前</button>
        <button @click="age = 24">数据源发生改变,视图更新之后</button>
    </template>
  • 运行效果:

2.7 beforeUmount

  • 组件实例被 卸载之前 调用;
  • 可访问
    • 组件实例东西【数据源、函数、计算属性】;
    • 组件试图中的DOM元素。
  • 示例代码:与 8.8 代码放在一起,好对比。

2.8 unmounted

  • 组件实例被 卸载之后 调用;

  • 可访问

    • 组件实例东西【数据源、函数、计算属性】;
  • 不能访问

    • 组件试图中的DOM元素;
  • 一般在这个生命周期函数里,我们可以手动清理一些副作用,例如计时器、DOM事件监听器或者与服务器的连接。

  • 示例展示:

    • 目标文件 App.vue(父组件):

      html 复制代码
      <script>
          import Vue1 from '@/components/23-生命周期/1.vue'
          export default {
              components: { Vue1 },
              data: () => ({
                  checked: false
              })
          }
      </script>
      
      <template>
          <h4>App组件</h4>
          <label>
              是否显示子组件
              <input type="checkbox" v-model="checked">
          </label>
          <br>
          <Vue1 v-if="checked"></Vue1>
      </template>
    • 目标文件: 1.vue(子组件):

      js 复制代码
      /**
      * 组件实例 被卸载之前 调用
      * 能访问:组件实例、data数据、methods方法、计算属性、侦听器、props等等
      * 不能访问:
      * */
      beforeUnmount() {
          console.log('-------------------------------')
          console.log('beforeUnmount 组件实例 被卸载之前 调用')
          console.log('能够访问props:', this.$props.subtitle)
          console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd)
          this.showMessage()
          console.log('能访问:DOM元素:', document.getElementById('age').innerHTML)
      },
      /**
      * 在 组件实例 被卸载之后 调用
      * 能访问:
      *    props、data数据、methods方法、计算属性、侦听器、组件实例this等等
      * 不能访问:
      *    组件视图中的DOM元素
      * */
      unmounted() {
          console.log('-------------------------------')
          console.log('unmounted 组件实例 被卸载之后 调用')
          console.log('能够访问props:', this.$props.subtitle)
          console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd)
          this.showMessage()
          console.log('能访问:DOM元素:', document.getElementById('age').innerHTML)
      }
  • 运行效果:

三、 生命周期总结(选项式+组合式)

3.1 组合式API:

钩子函数 调用时机 可以访问 不能访问
onBeforeMount 组件视图渲染之前 数据源、函数、计算属性、侦听器、props等等 组件中的DOM元素
onMounted 组件视图渲染之后 数据源、函数、计算属性、侦听器、propsDOM元素等等
onBeforeUpdate 数据发生变化,视图重新渲染之前 数据源、函数、计算属性、侦听器、props、视图重新渲染之前的DOM元素等等 视图重新渲染之后的DOM元素
onUpdated 数据源发生变化,视图重新渲染之后 数据源、函数、计算属性、侦听器、props、视图重新渲染之后的DOM元素等等 视图重新渲染之前的DOM元素
onBeforeUnmount 组件卸载之前 数据源、函数、计算属性、侦听器、props、组件的DOM元素等等
onUnmounted 组件卸载之后 数据源、函数、计算属性、侦听器、props等等 组件DOM元素

3.2 选项式API

钩子函数 调用时机 可以访问 不能访问
beforeCreate 组件 实例 初始化之前 自定义属性(props)等 data数据、methods方法、组件实例this、计算属性、侦听器、视图DOM元素
🔺created 组件 实例 初始化 成功之后 自定义属性、data数据、methods方法、组件实例this、计算属性、侦听器等 视图DOM元素
beforeMount 组件 渲染 之前 自定义属性、data数据、methods方法、组件实例this、计算属性、侦听器等 视图DOM元素
🔺mounted 组件 渲染成功 之后 组件实例thisdata数据、methods方法、计算属性、侦听器、视图DOM元素等
beforeUpdate 数据发生改变,DOM更新之前 组件实例thisdata数据、methods方法、计算属性、侦听器、自定义属性(props)、组件更新之前的DOM元素等 组件更新之后的DOM元素
updated 数据发生改变,DOM更新之后 组件实例thisdata数据、methods方法、计算属性、侦听器、自定义属性(props)、组件更新之后的DOM元素等 组件更新之前的DOM元素
beforeUnmount 组件实例 被卸载之前 组件实例thisdata数据、methods方法、计算属性、侦听器、自定义属性(props)、组件视图DOM元素等等
unmounted 组件实例 被卸载之后 组件实例thisdata数据、methods方法、计算属性、侦听器、自定义属性(props)等等 组件视图DOM元素
相关推荐
Jiaberrr6 分钟前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
m0_689618281 小时前
水凝胶发生器,不对称设计妙,医电应用前景广
笔记
Ace'1 小时前
每日一题&&学习笔记
笔记·学习
Tiffany_Ho1 小时前
【TypeScript】知识点梳理(三)
前端·typescript
挥剑决浮云 -1 小时前
Linux 之 安装软件、GCC编译器、Linux 操作系统基础
linux·服务器·c语言·c++·经验分享·笔记
安冬的码畜日常2 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js
太阳花ˉ2 小时前
html+css+js实现step进度条效果
javascript·css·html
新晓·故知2 小时前
<基于递归实现线索二叉树的构造及遍历算法探讨>
数据结构·经验分享·笔记·算法·链表