How to access Vuex from Vue Plugin?
Asked Answered
S

4

15

How can I access my store from my plugin? Console returns undefined.

import store from './store';

export default {
    install(vue, opts){
        Vue.myGlobalFunction = function(){
            console.log(store);
        }
    }
}
Shafer answered 31/10, 2018 at 17:58 Comment(0)
F
8

I recently had to do this too to make a pouchDb plugin, and came up with a new way.

When you create your first Vue object, you can do this.

import PouchDb from '@/pouch_db/PouchDbPlugin'

let DefaultVue = Vue.extend({
  components: {App},
  store,
  created () {
    Vue.use(PouchDb, this.$store) // Create it by passing in the store you want to use
  }
})

My plugin adds an additional store, and it's own mutations and getters.

export default {
  install (Vue, store) {
    store.registerModule('PouchDb', pds)
    const pouchDb = new PouchDb(store)
    Vue.pouchDb = pouchDb
    Vue.prototype.$pouchDb = pouchDb
  }
}

Inside the constructor, I store the store

class PouchDb {
  constructor (store) {
    this.store = store
    // ... etc.
  }
  // ... more functions
}

And then use it in other functions

class PouchDb {
    // ... constructor and other functions
    async addSync (docId) {
       this.store.dispatch('PouchDb/addSync', docId)
    }
}

It's a bit of a cheat to pass in the store, but seems to work nicely. It's usable throughout the app like this

// Inside vuex store
Vue.pouchDb.addSync(// ...etc)

// inside component
this.$pouchDb.removeSync(// ...etc)
Frustule answered 7/6, 2019 at 21:35 Comment(0)
S
6

See official guide here where it states

A Vue.js plugin should expose an install method. The method will be called with the Vue constructor as the first argument, along with possible options:

So you can do this, very easily.

Vue.use( {
    install(Vue){
        Vue.prototype.$something = function (){
            this.$store...etc
        }
    } 
} )

To use, simply do this.$something() in a components methods/computed etc, or directly in the component markup as {{$something()}}

This will remove the plugin needing to know where the store actually resides, while still allowing you to utilize the store within the plugin.

This is because it will inherit the scope of whatever component utilizes it, thus providing access to all of the components instance properties, including things like $store, $router as well any of it's local properties such as computed properties, parents etc. Essentially the plugin functions as if it is directly a part of the component (eg if you used it as a mixin).

Studdingsail answered 3/5, 2019 at 3:54 Comment(2)
I found that you need to use the normal function function notation- not using arrow function notation. I thought it a little odd, but I upon further thought, the arrow notation is taking in some other context and the $store variable is found on Vue's context.Viceregent
@Viceregent it's because of lexical scope and how the install method is resolved. In that particular example, using an arrow function would give it lexical scope of the install function. In the given example, I believe Vue.prototype.fn is resolved with fn.apply(this) behind the scenes, meaning a plain function would give it lexical scope of the Vue.prototype call. I agree it's confusing, I guess it just boils down to understanding how lexical scope works, and how certain aspects of Vue (eg extending prototype or using functions in the computed portion of components) works.Studdingsail
P
4

For Vue 3

Incase if you wonder, how to do it in Vue 3, You can use the following.

plugin.js

export default {
  install(app) { // app instance
     console.log(app.config.globalProperties.$store)
  }
}

main.js

import store from './pathtostore'
import plugin from './plugin'

createApp(...).use(store).use(plugin)
Prolate answered 10/4, 2021 at 12:16 Comment(0)
C
1

When app starts, you import your store and "append" it to Vue, globally.

Now, if you use() your plugin, the first parameter of install() is always Vue itself, and in this moment Vue already has access to the store, in the install method you can simply start

install(vue, opts) {
  ... here your can acces to vue.$store ....
}
Charlottcharlotta answered 13/7, 2019 at 6:42 Comment(3)
I don't know if something changed but I Vue.use my plugin in my Nuxt app and vue.$store is undefined although the Nuxt app has vuex.Willman
I am not under nuxt evenvironmentCharlottcharlotta
thats because nuxt has a speacial method for making/injecting pluginPrehension

© 2022 - 2024 — McMap. All rights reserved.