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

Bruno Mazzardo
  • 1,586
  • 1
  • 15
  • 27
Louis Ameline
  • 2,779
  • 1
  • 25
  • 25

6 Answers6

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.

tony19
  • 125,647
  • 18
  • 229
  • 307
Daksh M.
  • 4,589
  • 4
  • 30
  • 46
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

GMaiolo
  • 4,207
  • 1
  • 21
  • 37
  • 1
    My point is exactly that I have no main.js file where I would write `new Vue` and declare store. – Louis Ameline Jun 12 '18 at 19:13
  • @LouisAmeline were you able to take a look at these [Quasar docs](https://quasar-framework.org/guide/app-vuex-store.html) 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. – GMaiolo Jun 12 '18 at 19:16
  • 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 you – Louis Ameline Jun 12 '18 at 19:25
  • @LouisAmeline [take a look at this](https://forum.quasar-framework.org/topic/1953/adding-a-store-vuex-later) from the Quasar official forums. If you manually create the respective folder and file, it will take it by itself from there. – GMaiolo Jun 12 '18 at 19:28
  • 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! – Louis Ameline Jun 12 '18 at 19:39
  • 1
    @LouisAmeline fair enough, remember that it's better to avoid using the `store` as an instance property as it already is :) – GMaiolo Jun 12 '18 at 19:47
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!

tony19
  • 125,647
  • 18
  • 229
  • 307
Liju Kuriakose
  • 445
  • 3
  • 11
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`
  }
}
martenc
  • 668
  • 6
  • 7
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
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'
  }
})
iraj jelodari
  • 3,118
  • 3
  • 35
  • 45