写点什么

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

作者:空城机
  • 2022 年 7 月 12 日
  • 本文字数:1657 字

    阅读完需:约 5 分钟

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

生命周期

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


这些钩子中都应该在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 进行转换。

发布于: 刚刚阅读数: 3
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
不习惯的Vue3起步四 の 生命周期&provide/inject_Vue3_空城机_InfoQ写作社区