问题
In main.js
I have something like this:
import { myUtilFunc} from './helpers';
Object.defineProperty(Vue.prototype, '$myUtilFunc', { value: myUtilFunc });
In this way I have acess to myUtilFunc
across whole application with this.$myUtilFunc
But how can I achieve the same in setup()
method in Vue 3 if I don't have access to this
?
回答1:
In Vue 3, setup
has an optional second argument for context
. You can access the Vue instance through context.root
instead of this
:
setup(props, context) {
context.root.$myUtilFunc // same as `this.$myUtilFunc` in Vue 2
}
Things you can access through context
:
context.attrs
context.slots
context.parent
context.root
context.emit
回答2:
While Dan's answer is correct, I would like to provide an alternative mentioned in the comments to the accepted answer. There are pros and cons to each, so, you need to choose based on your needs.
To understand why the code below works, it is important to remember, that provided properties are transitive in the tree of components. I.e. inject('foo')
will look for 'foo' in every parent going up the hierarchy all the way to the app
; there is no need to declare anything in the middle wrappers.
So, we can write something like this:
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')
And then, in some 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>
Obviously, you can use
provide<T>(key: InjectionKey<T> | string, value: T): void
and
inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
anywhere in your code, doesn't have to be app.provide()
You can also provide values, even the global store, like this, just don't forget to use ref()
or reactive()
as needed.
In short, whenever you would prefer dependency injection, provide/inject are your friends.
来源:https://stackoverflow.com/questions/60202724/vue-3-composition-api-and-access-to-vue-instance