虽然 Dan 的答案是正确的,但我想提供 cmets 中提到的替代答案来替代已接受的答案。各有优劣,所以需要根据自己的需要来选择。
要理解为什么下面的代码有效,重要的是要记住,提供的属性在组件树中是可传递的。 IE。 inject('foo') 将在每个父级中查找“foo”,一直到app;无需在中间包装器中声明任何内容。
所以,我们可以这样写,其中 globalDateFormatter() 只是我们想在树下的任何组件中使用的示例函数:
main.js
import { createApp } from 'vue'
import App from './App.vue'
const globalDateFormatter = (date) => {
return '[' + date.toLocaleString() + ']'
}
const app = createApp(App)
app.provide('globalDateFormatter', globalDateFormatter) // <-- define here
app.mount('#app')
然后,在一些 DeepDownComponent.vue 中:
<template>
<p> {{ fmt(new Date()) }} </p>
</template>
<script>
import { inject } from 'vue'
export default {
setup(){
const fmt = inject('globalDateFormatter', x => x.toString())
// ^-- use here, optional 2nd parameter is the default
return {fmt}
}
}
</script>
显然,您可以直接导入并使用provide和inject,并带有以下签名
provide<T>(key: InjectionKey<T> | string, value: T): void
和
inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
代码中的任何位置,不必是app.provide()
你也可以提供值,甚至是全局存储,像这样,只是别忘了根据需要使用ref() 或reactive()。
简而言之,只要你喜欢依赖注入,provide/inject 就是你的朋友。