Javascript Vue 3合成API和对Vue实例的访问

Javascript Vue 3合成API和对Vue实例的访问,javascript,vue.js,vue-component,vuejs3,vue-composition-api,Javascript,Vue.js,Vue Component,Vuejs3,Vue Composition Api,在main.js中,我有如下内容: import { myUtilFunc} from './helpers'; Object.defineProperty(Vue.prototype, '$myUtilFunc', { value: myUtilFunc }); 通过这种方式,我可以通过this.$myUtilFunc在整个应用程序中访问myUtilFunc 但是,如果我无法访问Vue 3中的setup()方法this,如何在该方法中实现相同的功能?使用provide/inject 提供 c

main.js
中,我有如下内容:

import { myUtilFunc} from './helpers';
Object.defineProperty(Vue.prototype, '$myUtilFunc', { value: myUtilFunc });
通过这种方式,我可以通过
this.$myUtilFunc
在整个应用程序中访问
myUtilFunc

但是,如果我无法访问Vue 3中的
setup()
方法
this
,如何在该方法中实现相同的功能?

使用
provide
/
inject
提供

const-app=createApp(app);
app.provide('someVarName',someVar);//`在此处为所有组件提供一个变量
注入

// In *any* component
const { inject } = Vue;
...
setup() {
  const someVar = inject('someVarName');   // injecting variable in setup
}
<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>
请注意,您不必从应用程序根目录提供,但也可以从任何组件向其子组件提供:

//在*任意*组件中
设置(){
...
},
提供(){
返回{
someVarName:someVar
}
}

原始答案 [编辑:虽然我下面的原始答案对
上下文
属性仍然有用,但不建议再使用
上下文.root
,后者在中不再提及,可能很快就会被弃用。]

在Vue 3中,
设置
有一个可选的第二个参数,用于
上下文
。您可以通过
context.root而不是
this
访问Vue实例:

设置(道具、背景){
context.root.$myUtilFunc//与Vue 2中的'this.$myUtilFunc'相同
}
您可以通过
上下文访问的内容

context.attrs
context.slots
context.parent
context.root
context.emit

虽然Dan的回答是正确的,但我想提供评论中提到的对已接受答案的替代方案。每种方法都有优点和缺点,因此,您需要根据自己的需要进行选择

要理解下面代码的工作原理,必须记住,提供的属性在组件树中是可传递的。也就是说,
inject('foo')
将在层次结构上一直到
应用程序的每个父级中查找'foo';没有必要在中间包装中声明任何东西。
因此,我们可以这样写,其中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')

inject(key:InjectionKey | string,defaultValue:T):T
代码中的任何位置都不必是
app.provide()

您也可以提供值,甚至像这样的全局存储,只是不要忘记根据需要使用
ref()
reactive()


简言之,只要你喜欢依赖注入,提供/注入就是你的朋友。

@Ammamon
提供/注入
,答案的第一部分
provide<T>(key: InjectionKey<T> | string, value: T): void
inject<T>(key: InjectionKey<T> | string, defaultValue: T): T