21、Vue 3 (2024 版)基础笔记 - 生命周期与应用

作者: 温新

图书: 【Vue 3 setup 使用实记】

阅读: 417

时间: 2024-11-21 15:13:44

掌握 Vue 3 的生命周期非常重要。本篇文章不会讲什么生命周期,只记录代码。但是生命周期的图还是展示一下。

Vue 3 生命周期

Vue 3 有的生命周期有 4 种以及 8 个 生命周期函数,如下:

  • 创建期
    • beforeCreate、created
  • 挂载期
    • beforeMount、mounted
  • 更新期
    • beforeUpdate、updated
  • 销毁期
    • beforeUnmount、unmounted

下面通过代码演示一下:

src/App.vue

<template>
    <h3>生命周期函数演示</h3>
    <p>{{ username }}</p>
    <button @click="clickHandler">换一个</button>
</template>

<script setup lang="ts">
    // 当使用 setup 语法时, beforeCreate 和 created 不需要
    import { 
        ref,
        onMounted, 
        onUpdated, 
        onUnmounted, 
        onBeforeMount, 
        onBeforeUpdate, 
        onBeforeUnmount
    } from 'vue';

    // 使用事件用户演示更新操作
    const username = ref<string>("王美丽")
    const clickHandler = () => {
        username.value = "王丽丽"
    }

    onBeforeMount(() => {
        console.log("beforeMount: 组件即将被挂载到 DOM 中");
    })

    onMounted(() => {
        console.log('mounted: 组件已经被成功挂载到 DOM 中');
        // 这里可以执行依赖于 DOM 的操作,如第三方库初始化、DOM 查询、添加事件监听器等
    })

    onBeforeUpdate(() => {
        console.log('beforeUpdate: 组件即将更新');
        // 可以在此对比旧的 props/state 和新的 props/state,进行必要的状态同步
    })

    onUpdated(() => {
        console.log('updated: 组件已完成更新,DOM 已同步');
        // 这里可以处理组件更新后与 DOM 相关的操作,如重新计算尺寸、更新图表数据等
    })

    onBeforeUnmount(() => {
        console.log('beforeUnmount: 组件即将被卸载');
        // 可能做一些清理工作:暂停正在进行的动画、取消网络请求、清理定时器等
    })

    onUnmounted(() => {
        console.log('unmounted: 组件已被卸载,释放资源');
        // 这里执行必要的清理工作,如移除事件监听器、取消定时器、解绑外部资源等
    })

</script>

Vue 3 生命周期的应用

这里使用生命周期获取 ref 获取 DOM 结构发送网络请求获取数据

使用 setup 语法获取 DOM 元素时,需要注意:

  • 1、setup 语法中,无法使用 $this

  • 2.子组件使用 setup 语法糖时,需要添加 defineExpose 方法导出

  • 3、vue 3 中, ref 在普通标签上获取真实 DOM 元素为 ref.value

  • 4、vue 3 在自定义组件上获取真实 DOM 元素的方法为 childRef.value.$el

使用 ref 获取 DOM 结构

先来看看直接在组件中获取 DOM 元素的用法:

src/App.vue

<template>
    <div ref="refDiv">setup 语法中,获取 DOM 元素</div>
</template>

<script setup lang="ts">
    import { ref,onMounted} from 'vue';


    // 定义一个名为refDiv的响应式变量,类型为Ref<HTMLDivElement | null>
    // 初始值设为null,表示在组件挂载之前,refDiv.value为null
    // 在组件挂载后,refDiv.value将指向一个HTMLDivElement实例
    const refDiv = ref<HTMLDivElement|null>(null)


    onMounted(() => {
        refDiv.value.style.background = 'lightpink'
        // 使用 refDiv.value 获取 DOM 元素
        console.log(refDiv.value)        
    })

</script>

父组件中获取子组件的 ref DOM 元素

1、子组件

src/components/RefDomDemo.vue

<template>
    <!-- 1. 显示由username变量控制的文本 -->
    <div>{{ username }}</div>
</template>

<script setup lang="ts">
    // 2. 导入Vue的ref函数,用于创建响应式变量
    import { ref } from 'vue';

    // 3. 创建一个名为username的响应式变量,类型为string
    //    初始值设为'王美丽'
    const username = ref<string>('王美丽');

    // 4. 使用defineExpose暴露username变量到父组件
    //    这使得父组件可以通过模板插槽props、$refs或$attrs访问到该变量
    defineExpose({
        username
    })
</script>
2、父组件

src/App.vue

<template>
    <!-- 1. 引入并渲染子组件 RefDomDemo,同时为其设置 ref="usernameRef" -->
    <!--    这使得父组件可以通过 usernameRef 变量访问到子组件的实例 -->
    <RefDomDemo ref="usernameRef"></RefDomDemo>
</template>

<script setup lang="ts">
    import { ref, onMounted } from 'vue';
    import RefDomDemo from './components/RefDomDemo.vue';

    // 2. 创建一个名为 usernameRef 的响应式变量,类型为Ref<null>
    //    初始值设为 null,表示在组件挂载之前,usernameRef.value为null
    //    在组件挂载后,usernameRef.value 将指向 RefDomDemo 子组件实例
    const usernameRef = ref<null>(null);



    onMounted(() => {
        usernameRef.value.$el.style.color = 'red';
        console.log(usernameRef);
    });
</script>

通过生命周期函数获取数据

src/App.vue

<template>
    <div>
        <ul>
            <li v-for="article in articles" :key="article.id">{{ article.title }}</li>
        </ul>
    </div>

</template>

<script setup lang="ts">
    import { ref, onMounted } from 'vue';

    const articles = ref<object[]>([]);

    onMounted(() => {
        // 模拟网络请求获取数据
        const response = [
            {id:1, title:"PHP"},
            {id:2, title:'Vue 3'}
        ]

        articles.value = response
    });
</script>
请登录后再评论
albert 2024-05-13 19:50:34
更新期
deforeUpdate、updated
应该是beforeUpdate、updated 即 d -> b
2024-07-08 17:11:56
谢谢指正,这就修改