Use Vue.js plugin in Vuex Store module

Viewed 9217

I am trying to use a Vue.js plugin inside of a Vuex Store module.

In a component, I am able to call it like this: this.$plugin(). However, in a module, this is not set. I thought Vue.$plugin() would work since I initialize the plugin with Vue.use(plugin) and Vue being a global variable, but it doesn't.

How do I reference the plugin from a module?

4 Answers

The cleanest way I found is to import Vue in the store/module and then use the plugin via the Vue prototype.

import Vue from 'vue';

// .. in some logic
Vue.prototype.$dialog.alert('Something went wrong');

This question was answered by Bert in the example provided here: https://codesandbox.io/s/jp4xmzl0xy

    import Vue from 'vue'
    import App from './App'
    import Notifications from 'vue-notification'
    import Vuex from "vuex"
    Vue.use(Notifications)
    Vue.use(Vuex)
    
    let notifier = new Vue()
    
    
    const store = new Vuex.Store({
      state:{},
      actions:{
        notify(context, payload){
          notifier.$notify(payload)
        }
      }
    })
    
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      store,
      template: '<App/>',
      components: { App }
    })

Pass in the vue instance as an argument

Another option is to pass the vue instance as an argument for your action.

// Vue component
{
  methods: {
    const vm = this
    this.$store.dispatch('someaction', { vm })
  }
}

// Store action
{
  someaction (context, { vm }) {
    vm.$dialog.alert('Something went wrong')
  }
}

There's a couple of other ways I've found. Honestly not sure which is the best though. I really don't like importing Vue and calling prototype methods. Seems like a complete antipattern and particularly difficult when it comes to testing using localVue as the actions have been coupled to global Vue.

  1. I'm pretty sure you're not supposed to do this but you can access the vue instance of the store from within an action using this._vm.$notify

  2. You can create a store plugin:

const notifyStore = (store) => {
  store.$notify = store._vm.$notify
}
  1. Create notify as a standalone module
import Vue from 'vue'

let notifier = new Vue()

export default notifier
  1. A combination of the two
import notifier from './notifier'

const notifyStorePlugin = (store) => {
  store.$notify = notifier.$notify
}

I'm not saying this is the definitive answer on this. I'm also very open to feedback and other suggestions.

Related