Vue 3 组合 API 和访问 Vue 实例
Vue 3 composition API and access to Vue instance
在 main.js
我有这样的东西:
import { myUtilFunc} from './helpers';
Object.defineProperty(Vue.prototype, '$myUtilFunc', { value: myUtilFunc });
通过这种方式,我可以使用 this.$myUtilFunc
在整个应用程序中访问 myUtilFunc
但是,如果我无法访问 this
,我如何在 Vue 3 的 setup()
方法中实现相同的目的?
使用provide
/inject
提供
const app = createApp(App);
app.provide('someVarName', someVar); // `Provide` a variable to all components here
注入:
// In *any* component
const { inject } = Vue;
...
setup() {
const someVar = inject('someVarName'); // injecting variable in setup
}
请注意,您不必从应用程序根目录提供,但也可以 provide
从任何组件到仅其子组件:
// In *any* component
setup() {
...
},
provide() {
return {
someVarName: someVar
}
}
原回答
[编辑:虽然我下面的原始答案对 context
属性仍然有用,但不再建议使用 context.root
,guide 中不再提及,可能很快就会弃用。]
在 Vue 3 中,setup
有一个可选的第二个参数 context
。您可以通过 context.root
而不是 this
:
访问 Vue 实例
setup(props, context) {
context.root.$myUtilFunc // same as `this.$myUtilFunc` in Vue 2
}
您可以通过 context
访问的内容:
context.attrs
context.slots
context.parent
context.root
context.emit
虽然 Dan 的回答是正确的,但我想提供评论中提到的替代答案以接受答案。各有优缺点,大家要根据自己的需要来选择。
要理解下面代码的工作原理,请务必记住,提供的属性在组件树中是可传递的。 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 就是您的朋友。
在 main.js
我有这样的东西:
import { myUtilFunc} from './helpers';
Object.defineProperty(Vue.prototype, '$myUtilFunc', { value: myUtilFunc });
通过这种方式,我可以使用 this.$myUtilFunc
myUtilFunc
但是,如果我无法访问 this
,我如何在 Vue 3 的 setup()
方法中实现相同的目的?
使用provide
/inject
提供
const app = createApp(App);
app.provide('someVarName', someVar); // `Provide` a variable to all components here
注入:
// In *any* component
const { inject } = Vue;
...
setup() {
const someVar = inject('someVarName'); // injecting variable in setup
}
请注意,您不必从应用程序根目录提供,但也可以 provide
从任何组件到仅其子组件:
// In *any* component
setup() {
...
},
provide() {
return {
someVarName: someVar
}
}
原回答
[编辑:虽然我下面的原始答案对 context
属性仍然有用,但不再建议使用 context.root
,guide 中不再提及,可能很快就会弃用。]
在 Vue 3 中,setup
有一个可选的第二个参数 context
。您可以通过 context.root
而不是 this
:
setup(props, context) {
context.root.$myUtilFunc // same as `this.$myUtilFunc` in Vue 2
}
您可以通过 context
访问的内容:
context.attrs
context.slots
context.parent
context.root
context.emit
虽然 Dan 的回答是正确的,但我想提供评论中提到的替代答案以接受答案。各有优缺点,大家要根据自己的需要来选择。
要理解下面代码的工作原理,请务必记住,提供的属性在组件树中是可传递的。 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 就是您的朋友。