最新版vue3+TypeScript开发入门到实战教程之生命周期函数

#1、概述 组件的生命周期,即从组件的创建到销毁,所经历的过程。以下是在官网的定义: Vue组件实例在创建时要经历一系列的初始化步骤,在此过程中Vue会在合适的时机,调用特定的函 数,从而让开发者有机会在特定阶段运行自已的代码,这些特定的函数统称为:生命周期钩子 组件的生命周期分为四个阶段:

  • 创建阶段,创建前、创建后
  • 挂载阶段,挂载前、挂载后
  • 更新阶段,更新前、更新后
  • 销毁阶段,销毁前、销毁后

1.1创建阶段

创建阶段,是组件被父组件引用。父组件渲染模版时,发现有子组件,于是创建子组件。

  • 创建前会调用开发者设置的函数,该函数被称作生命周期钩子
  • 创建后,创建完成调用函数

1.2挂载阶段

挂载的含义,是子组件被创建后,准备在浏览器中挂载,显示。

  • 挂载前,子组件未显示
  • 挂载后,子组件可在浏览器中显示

更新阶段

  • 页面更显前调用,首次挂载完成不调用
  • 页面更新后调用,首次挂载完成不调用

销毁阶段

  • 销毁前,当组件被销毁前调用
  • 销毁后,组件被销毁后调用

2、对比Vue2中生命周期函数

  • 创建App组件,引用Fish组件
  • 在Fish内声明所有钩子函数
  • 打印钩子函数调用顺序 App组件
xml 复制代码
<template>
  <div class="app">
    <button @click="isShow=!isShow">销毁子组件</button>
    <fish v-if="isShow"/>
  </div>
</template>
<script>
import Fish from './Fish.vue'
export default {
  data () {
    return {
      isShow: true
    }
  },
  components: { Fish }
}
</script

Fish组件

xml 复制代码
template>
  <div class="container">
    <h1>我是子组件</h1>
    <h2>{{ num }}</h2>
    <button @click="num++">增加</button>
  </div>
</template>
<script>
export default {
  data () {
    return {
      num: 0
    }
  },
  beforeCreate () {
    console.log('beforeCreate')
  },
  created () {
    console.log('created')
  },
  beforeMount () {
    console.log('beforeMount')
  },
  mounted () {
    console.log('mounted')
  },
  beforeUpdate () {
    console.log('beforeUpdate')
  },
  updated () {
    console.log('updated')
  },
  beforeDestroy () {
    console.log('beforeDestroy')
  },
  destroyed () {
    console.log('destroyed')
  }
}
</script>

查看运行结果 首次点开页面,依次调用:beforeCreate、created、beforeMount、mounted 当点击按钮更新数据时,依次调用beforeUpdate、updated。 当点击按钮销毁子组件时,依次调用beforeDestroy、destroyed

3、Vue3生命周期函数

在Vue3中,生命周期函数与Vue2是有差别的。 Vue2的生命周期

  • 创建阶段,beforeCreate创建前、created创建后
  • 挂载阶段,beforeMount挂载前、mounted挂载后
  • 更新阶段,beforeUpdate更新前、updated更新后
  • 销毁阶段,beforeDestroy销毁前、destroyed销毁后 Vue3的生命周期
  • 创建阶段,setup
  • 挂载阶段,onBeforeMount挂载前、onMounted挂载后
  • 更新阶段,onBeforeUpdate更新前、onUpdated更新后
  • 销毁阶段,onBeforeUnmount销毁前、onUnmounted销毁后 App组件
xml 复制代码
<template>
  <div class="app">
    <h2>我是父组件</h2>
    <button @click="isShow=!isShow">销毁子组件</button>
    <Fish v-if="isShow" />
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Fish from './components/Fish.vue';
let isShow = ref(true)
</script>

Fish组件

xml 复制代码
<template>
  <div>
    <h1>我是子组件</h1>
    <h2>{{ num }}</h2>
    <button @click="num++">增加</button>
  </div>
</template>
<script setup lang="ts">
import {onBeforeMount, onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount, ref, onUnmounted} from 'vue'
let num = ref(0);
console.log('createed')
onBeforeMount(() => {
  console.log('onBeforeMount')
})
onMounted(() => {
  console.log('onMounted')
})
onBeforeUpdate(() => {
  console.log('onBeforeUpdate')

})
onUpdated(() => {
  console.log('onUpdated')
})
onBeforeUnmount(() => {
  console.log('onBeforeUnmount')

})
onUnmounted(() => {
  console.log('onUnmounted')
})
</script>

运行效果: 打开页面,首先依次调用created、onBeforeMount、onMounted。注意created函数位置 当点击按钮增加,依次调用onBeforeUpdate、onUpdated 当点击按钮销毁子组件,依次调用onBeforeUnmount,onUnmounted

4、父组件先调用onMounted还是子组件先调用onMounted

父组件先挂载,然后调用子组件生命周期函数,完成。最后父组件挂载完成,如下图: 这里调用先后顺序:

  • 父组件:onBeforeMount
  • 子组件created
  • 子组件onBeforeMount
  • 子组件onMounted
  • 父组件:onMounted

5、Vue3自定义Hooks

什么是自定义Hooks,看下官方给的定义: 在 Vue 3 中,hooks 本质上是一种函数封装模式,用于将组件中可复用的逻辑(特别是涉及响应式状态、生命周期等的逻辑)抽取出来,形成独立的、可组合的函数。 它是 Vue 3 组合式 API(Composition API)的核心实践方式。 举一个简单例子,当我在Fish组件中,有两种业务。一种是淡水鱼业务、一种是海洋鱼业务。 两者业务都合在Fish组件中,数据和定义都混合在一起,不利于代码阅读维护。 于是自定义Hooks的出现,解决模块化变成的问题,将淡水鱼写成一个模块、海洋鱼一个模块。每个模块都有生命周期钩子函数。

  • 创建Fish组件
  • 创建淡水鱼模块RiverFish.ts,数据有name,num,change函数
  • 创建海洋鱼模块Oceanfish.ts,数据有name,price,change函数 Fish组件代码
xml 复制代码
<template>
  <div>
    <h1>我是子组件</h1>
    <h2>淡水鱼:{{ name }}</h2>
    <h2>淡水鱼数量:{{ num }}</h2>
    <button @click="change()">增加数量</button>
     <h2>海洋鱼:{{ ocean.name }}</h2>
    <h2>海洋鱼价格:{{ ocean.price }}</h2>
    <button @click="ocean.change()">增加价格</button>
  </div>
</template>
<script setup lang="ts">
import { riverfish } from '@/hooks/Riverfish'
import { oceanfish } from '@/hooks/Oceanfish'
const { name, num, change } = riverfish();
const ocean = oceanfish();
</script>

RiverFish.ts模块代码

javascript 复制代码
import { ref,onMounted } from 'vue'
export function riverfish() {
  let name = ref('鲫鱼')
  let num = ref(0)
  function change() {
    num.value++
    name.value+='~'
  }
  onMounted(() => {
    console.log('Riverfish:onMounted')
  });
  return {
    name,
    num,
    change,
  }
}

Oceanfish.ts模块代码

javascript 复制代码
import { ref ,onMounted} from 'vue'
export function oceanfish() {
  let name = ref('鲨鱼')
  let price = ref(0)
  function change() {
    price.value++
    name.value+='~'
  }
  onMounted(() => {
    console.log('Oceanfish:onMounted')
  });
  return {
    name,
    price,
    change,
  }
}

文件目录结构如下图: 运行结果下图: 注意日志打印生命周期函数。在Hooks当中,可以使用声明周期函数、计算属性、响应式数据。

相关推荐
dsyyyyy11016 小时前
JavaScript变量
开发语言·javascript·ecmascript
kyriewen7 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
胡志辉的博客8 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖8 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty9 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
老毛肚9 小时前
软件测试期末考试
vue.js
小二·9 小时前
Next.js 15 全栈开发实战
开发语言·javascript·ecmascript
杨若瑜10 小时前
本地开发环境慢?localhost的锅!
vue.js
Rain50910 小时前
2.1 Nest.js 项目初始化与模块化架构
开发语言·前端·javascript·后端·架构·数据分析·node.js
拾年27511 小时前
从零手写 Ajax:用原生 XHR 搭建前后端交互全流程
前端·javascript·ajax