不习惯的 Vue3 起步四 の 生命周期 &provide/inject

举报
空城机 发表于 2022/07/12 09:11:34 2022/07/12
【摘要】 Vue3的生命周期大部分还是和Vue2一样,除了beforeCreate和created,这两个已经替换成setup了

生命周期

Vue3的生命周期大部分还是和Vue2一样,除了beforeCreatecreated,这两个已经替换成setup了。在 Vue3 中,需要哪个生命周期钩子也可以用哪个,使用时需要用import从Vue中进行导入。

选项API Hook(setup) 作用
beforeCreate 不需要 在实例初始化之后、进行数据侦听和事件/侦听器的配置之前同步调用
created 不需要 在实例创建完成后被立即同步调用
beforeMount onBeforeMount 在挂载开始前被调用,DOM尚未加载
mounted onMounted 在实例挂载完成后被调用,DOM加载已完成
beforeUpdate onBeforeUpdate 页面DOM更新前触发
updated onUpdated 页面DOM更新完触发
beforeUnmount onBeforeUnmount 在卸载组件之前触发
unmounted onUnmounted 卸载组件之后触发
errorCaptured onErrorCaptured 在捕获一个来自后代组件的错误是被触发,在vue2.5后出现
renderTracked onRenderTracked 跟踪虚拟 DOM 重新渲染时调用,状态跟踪,它会跟踪页面上所有响应式变量和方法的状态,当组件第一次渲染时,就会跟踪,然后生成一个event对象
renderTriggered onRenderTriggered 当虚拟 DOM 重新渲染被触发时调用,状态触发,不会跟踪每一个值,而是给出变化之的信息

这些钩子中都应该在setup中编写

官方API:https://v3.cn.vuejs.org/api/options-lifecycle-hooks.html

对于mounted这类生命周期API与vue2中使用是类似的,不过在vue3中新增了onRenderTrackedonRenderTriggered。这两种只能在开发环境中调试使用。

实例:

<template>
    <div> {{ val }} </div>
    <button @click="change">渲染</button>
</template>

<script setup lang="ts">
    import { ref, reactive, 
    onMounted, onBeforeMount, onBeforeUpdate, onUpdated, 
    onBeforeUnmount, onUnmounted, onErrorCaptured, onRenderTracked, onRenderTriggered} from "vue";
    let val = ref(1)
    function change():void {
        val.value = 1000
    }

    // 在 Dom 加载前触发
    onBeforeMount(() => {
        console.log('onBeforeMount')
    })
    // 在 Dom 加载完触发
    onMounted(() => {
        console.log('onMounted')
    })
    // 在页面更新前触发
    onBeforeUpdate(() => {
        console.log('onBeforeUpdate')
    })
    // 在页面更新完触发
    onUpdated(() => {
        console.log('onUpdated')
    })
    // 在组件销毁之前触发
    onBeforeUnmount(() => {
        console.log('onBeforeUnmount')
    })
        // 在组件销毁完成触发
    onUnmounted(() => {
        console.log('onUnmounted')
    })
    // 在每次渲染后收集响应式依赖
    onRenderTracked((event) => {
        console.log('onRenderTracked')
        console.log(event)
    })
    // 在每次触发页面重新渲染时自动执行
    onRenderTriggered(({key, target, type}) => {
        console.log('onRenderTriggered')
        console.log({key, target, type})
    })
</script>

效果:

在实例中可以看到,最初渲染中,onBeforeMount > onRenderTracked > onMounted,然后修改val数值,页面重新渲染触发onRenderTriggered > onBeforeUpdate > onUpdated

最后父组件中移除组件时,触发beforeUnmount > onUnmounted



provide提供/inject注入

当需要从父组件向子组件传递数据时,可以使用props,但是如果组件之间深度嵌套,深层的子组件需要父组件的部分内容,此时如果沿着props一层层传递,就会显得非常复杂(当然也可以使用)

在之前的《不习惯的Vue3起步一》 中曾经说到过attrs,这也可以用来获取祖先组件的属性,如果需要的数据不多,也可以使用这种方式。

通过provideinject的结合,无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。这特性有两部分:父组件有一个provide选项来提供数据,子组件有一个inject选项来使用这些数据。

首先准备一个父组件:

<template>
    <son></son>
</template>

<script setup lang="ts">
    import { ref, reactive, onMounted, provide, watch } from "vue";
    import son from './son.vue'

    let msg = ref('张三')
    provide("msgToChild", msg)
    watch(msg, (newval)=>{
        console.log(msg.value)
    })
</script>

然后是子组件:

<template>
    <h1> {{ msg }} 说:hello </h1>
    <button @click="change">改变</button>
</template>

<script setup lang="ts">
    import { ref,Ref, reactive, onMounted,useAttrs, inject } from "vue";

    let msg = inject('msgToChild')
    function change() {
        (msg as unknown as Ref<string>).value = Math.random().toString()
    }
</script>

效果: 在子组件中inject获取到了父组件数据,并且子组件中修改,父组件数据也会watch监听到修改

注意 :在上面的例子中,想要产生响应式改变,传递的数据需要ref或者reactive包裹。此外在子组件中获取到的msg类型其实是unknown,所以需要将其通过as进行转换。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。