Vue3 传值(provide、inject)

300 阅读1分钟

祖孙传值:provide inject

祖先组件

<template>
  <div>
    ChildComponent
  </div>
</template>

<script setup>
import { provide } from 'vue'
import Lazy from './Lazy'

// 提供依赖
const lazy = new Lazy()
const imgLoaded = () => {
  console.log('Image Loaded!')
}

provide('lazy', lazy)
provide('imgLoaded', imgLoaded)
</script>

子孙组件

<template>
  <div>
    GrandChildComponent 
  </div>
</template>

<script setup>
import { inject } from 'vue'

// 获取依赖
const lazy = inject('lazy')
const imgLoaded = inject('imgLoaded')

// 使用依赖
if (lazy) {
  lazy.doSomething()
}

if (imgLoaded) {
  imgLoaded()
}
</script>

provide()

  • 接收两个参数:第一个参数是要注入的 key,(字符串/ symbol),第二个参数是要注入的值

  • TypeScript:key 可以是一个被类型断言为 InjectionKey 的 symbol

    • InjectionKey 是一个 Vue 提供的工具类型,继承自 Symbol,可以用来同步 provide() 和 inject() 之间值的类型
  • 与注册生命周期钩子的 API 类似,provide() 必须在组件的 setup() 阶段同步调用

inject()

  • 父组件链上多个组件对同一个 key 提供了值 => 离得更近的组件将会“覆盖”链上更远的组件所提供的值

  • key 没有匹配到值,inject() 将返回 undefined,除非提供默认值

  • inject 第二个参数是可选的,即在没有匹配到 key 时使用的默认值。它也可以是一个工厂函数,用来返回某些创建起来比较复杂的值

  • 如果默认值本身就是一个函数,那么必须将 false 作为第三个参数传入,表明这个函数就是默认值,而不是一个工厂函数

  • 与注册生命周期钩子的 API 类似,inject() 必须在组件的 setup() 阶段同步调用。

  • TypeScript:key 可以是一个类型为 InjectionKey 的 symbol

TBC

  • 注册生命周期钩子的 API

  • InjectionKey

  • 工厂函数

  • 监听事件、vuex、attrs listener