With Vue-cli, where do I declare my global variables?
Asked Answered
F

6

11

In most Vue.js tutorials, I see stuff like

new Vue({
  store, // inject store to all children
  el: '#app',
  render: h => h(App)
})

But I'm using vue-cli (I'm actually using quasar) and it declares the Vue instance for me, so I don't know where I'm supposed to say that I want store to be a "Vue-wide" global variable. Where do I specify that? Thanks

Flanigan answered 12/6, 2018 at 18:12 Comment(0)
A
10

Yea, you can set those variables like this, in your entrypoint file (main.js):

Vue.store= Vue.prototype.store = 'THIS IS STORE VARIABLE';

and later access it in your vue instance like this:

<script>
export default {
  name: 'HelloWorld',
  methods: {
    yourMethod() {
        this.store // can be accessible here.
    }
  }
}
</script>

You can also see this in the vue-docs here.

Edit 1:

from the discussions in the comment sections about "no entrypoint file" in quasar's template.

what you can do is, to go to src/router/index.js, and there you will be able to get access to Vue, through which you can set a global variable like this:

...
import routes from './routes'

Vue.prototype.a = '123';

Vue.use(VueRouter)
...

and then if you console.log it in App.vue, something like this:

<script>
export default {
  name: 'App',
  mounted() {
        console.log(this.a);
  }
}
</script>

now, look at your console: enter image description here

You can also do the same in App.vue file in the script tag.

Anhydride answered 12/6, 2018 at 18:20 Comment(14)
What if there is no main.js as with quasar-cli?Clinton
@eric99 that's why I said entry point file. In the popular webpack template it is main.js, it could be something else depending on the project.Anhydride
The question came up in Louis's comment to @GMaiolo, In the quasar-cli generated app there appears to not be this entry point you are implying should be there.Tuneberg
Let me check quasar cli's code then and edit the answer appropriately.Anhydride
Cheers - your answer is good, I voted for it - but would like to figure that point out.Tuneberg
The entry point in my Quasar project is actually named App.vue, but I got your point.Flanigan
yea so i found out a way to do that, it's kind of hacky but does work with quasar cli.Anhydride
Yes, I just came to that conclusion - add the prototype property at the top of the script in App.vue.Tuneberg
@DakshMiglani - sorry was commenting to Louis, please share if different.Tuneberg
@RichardMatsen I did the same in router.jsAnhydride
Cheers @DakshMiglani. This doc App Plugins seems to be the official policy, but I do not agree that main.js was a major problem.Tuneberg
Yea it wasn't, just a little documentation magic was required hahaAnhydride
I was referring to the comment in Quasar's doc > There is a major problem with this approach: With a growing project, your main.js file was very likely to get cluttered and challenging to maintain...Tuneberg
Usually not, people make plugins when they have to set a lot of global variables.Anhydride
A
3

You don't need to make the store a global variable like that, as every component (this.$store) and the Vue instance itself have access to the store after the initial declaration.

Take a look at the Quasar docs for App Vuex Store.

store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    updateCount(state) {
      state.count += 1
    }
  }
})

main.js

import App from './App.vue'
import store from '/path/to/store.js'

new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

If you need to access the store from within a component you can either import it (as we did in main.js) and use it directly [note that this is a bad practice] or access using this.$store. You can read a bit more about that here.


In any case here's the official Getting Started guide from Vuex team

Alleviator answered 12/6, 2018 at 18:37 Comment(6)
My point is exactly that I have no main.js file where I would write new Vue and declare store.Flanigan
@LouisAmeline were you able to take a look at these Quasar docs I linked? I believe it does it for you, my code was for clarification. Try importing the store itself in the component in any case you need.Alleviator
Yes I did read it. At some point they write return this.$store.state.showcase.drawerState, except that this does not work because this.$store is not defined. I initialized the project without Vuex at first and added it later, maybe that's why it hasn't been taken care of automatically. The other answers do the trick though, I'll accept one of them. Thank youFlanigan
@LouisAmeline take a look at this from the Quasar official forums. If you manually create the respective folder and file, it will take it by itself from there.Alleviator
Well spotted, you are right. What I actually needed was to restart the dev server so it would acknowledge the new store folder and add it to Vue's prototype automatically. I upvote your answer as it was helpful in my specific case with Vuex, but I'll give the credit for right answer to Daksh Miglani as my question was also a bit wider, talking about Vue globals in general, and that he answered about that. Thank you though!Flanigan
@LouisAmeline fair enough, remember that it's better to avoid using the store as an instance property as it already is :)Alleviator
B
2

We could add the Instance Properties

Like this, we can define instance properties.

Vue.prototype.$appName = 'My App'

Now $appName is available on all Vue instances, even before creation.

If we run:

new Vue({
  beforeCreate: function() {
    console.log(this.$appName)
  }
}) 

Then "My App" will be logged to the console!

Burletta answered 12/6, 2018 at 18:23 Comment(1)
he said vue-cli.Anhydride
A
1

Slightly redundant to the aforementioned answer, but I found this to be simpler per the current Vuex state documentation at the time of this reply.

index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default function (/* { ssrContext } */) {
  const Store = new Vuex.Store({
    modules: {
      // example
    },
    state: {
      cdn_url: 'https://assets.yourdomain.com/'
    },

    // for dev mode only
    strict: process.env.DEV
  })

  return Store
}

...and then in your component, e.g. YourPage.vuex

export default {
  name: 'YourPage',
  loadImages: function () {
    img.src = this.$store.state.cdn_url + `yourimage.jpg`
  }
}
Acrylonitrile answered 7/10, 2019 at 2:1 Comment(0)
S
1

Joining the show a bit late, but the route I personally use in Quasar is to create a Boot file for my global constants and variables.

I create the Boot file (I call it global-constants.js but feel free to call it whatever).

/src/boot/global-constants.js

    import Vue from 'vue'

    Vue.prototype.globalConstants = {
      baseUrl: {
        website: 'https://my.fancy.website.example.com',
        api: 'https://my.fancy.website.example.com/API/v1'
      }
    }

    if (process.env.DEV) {
      Vue.prototype.globalConstants.baseUrl.website = 'http://localhost'
      Vue.prototype.globalConstants.baseUrl.api = 'http://localhost/API/v1'
    }

    if (process.env.DEV) {
      console.log('Global Constants:')
      console.log(Vue.prototype.globalConstants)
    }

Then add a line in quasar.conf.js file to get your Boot file to kick:

/quasar.conf.js

    module.exports = function (ctx) {
      return {
        boot: [
          'i18n',
          'axios',
          'notify-defaults',
          'global-constants' // Global Constants and Variables
        ],

Then to use it:

  • from Vuex
    • this._vm.globalConstants.baseUrl.api
    • for example: axios.post(this._vm.globalConstants.baseUrl.api + '/UpdateUserPreferences/', payload)
  • from Vue HTML page
    • {{ globalConstants.baseUrl.api }}
  • from Vue code (JavaScript part of Vue page
    • this.globalConstants.baseUrl.api
Scalf answered 14/9, 2020 at 15:52 Comment(0)
M
0

An alternative Vue3 way to this answer:

// Vue3

const app = Vue.createApp({})
app.config.globalProperties.$appName = 'My App'

app.component('child-component', {
  mounted() {
    console.log(this.$appName) // 'My App'
  }
})
Monocle answered 17/12, 2020 at 21:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.