Reputation: 23480
I have some global variables in Vue3 project defined like:
app.config.globalproperties.$locale = locale
then composable is created to dynamically return global variable:
import { getCurrentInstance ) from 'vue'
export function useGlobals(type) {
const app = getCurrentInstance()
const global = app.appContext.config.globalProperties[`$${type}`]
return { global }
}
then in vue components composable is imported and executed:
import { useGlobals } from '../path'
const { global } = useGlobals('locale')
now, global variable can be used.
But the problem arise when I import composable in js
files, there the appContext
is undefined.
My question is, is there a way we can get global variable or appContext
in js
files?
Upvotes: 8
Views: 6480
Reputation: 71
I attempted the answer suggested by @nikola-pavicevic, but it had a negative side effect of causing infinite recursion. For example, every time you import globals
, it has to run through the entirety of main.js
, which means initializing and mounting the app again. In production, the app appears to work correctly most of the time, but in my Jest unit tests, the recursion causes lots of issues.
To get around this, I created a GlobalVariableHolder.js
file that only contains the following:
const GlobalVariables = {};
export default GlobalVariables;
Then, in main.js
, I can import it like so:
import GlobalVariables from "./GlobalVariableHolder";
Then assign the variables:
// This line expects that you first assigned the variables to app.config.globalProperties.
GlobalVariables.variables = app.config.globalProperties;
Then, in the JS file where you need them, your import looks the same as before:
import GlobalVariables from "./GlobalVariableHolder";
And you have access to everything that was in app.config.globalProperties
like this:
GlobalVariables.variables.$thisIsAMethod(parameter);
This way, importing GlobalVariableHolder
doesn't spin up a new Vue instance every time.
Upvotes: 2
Reputation: 23480
Thanks to great suggestion from @tao (btw it is impossible to get appContext from app but that gives me an idea :)) issue is solved.
I created another export in main.js
, after app creation, with the all global properties:
const globals = app.config.globalProperties
export { globals }
or as a function (another @tao suggestion):
export const useGlobals = () => app.config.globalProperties
Now we can import globals in any js
file and use it like:
import { globals } from '../path/to/main.js'
globals.$locale
or from function :
import { useGlobals } from '../path/to/main.js'
const { $locale } = useGlobals()
Upvotes: 5
Reputation: 66
instead of creating your composable to get global props, you can use the provide/inject mechanism.
check the documentation here: https://vuejs.org/api/composition-api-dependency-injection.html#provide
Upvotes: 0