- I have a plugin and this plugin uses Vuex
// plugin.js
import Vuex from "vuex";
import store from "./store.js";
export default {
install(Vue, options) {
const storeInstance = new Vuex.Store(store);
Vue.prototype.$store = storeInstance;
}
};
- And in that plugin I import a store object.
// store.js
export default {
actions: {
SOME_RANDOM_ACTION({ state, commit }) {
console.log("some random action");
}
}
};
Dispatching actions and using state is fine and works as expected.
But when I add this plugin to another Vue instance that uses vuex, store object re-initializes with new state.
// index.js
import Vue from "vue";
import Vuex from "vuex";
import App from "./App.vue";
import plugin from "./plugin.js";
Vue.use(Vuex);
Vue.use(plugin);
new Vue({
// WARN when i uncomment this next line of code Vuex gets re-initialized with new object
// store: new Vuex.Store({ state: { hello: "hix" } }),
components: {
App
}
}).$mount("#app");
When you uncomment store initialization, store that was defined in the plugin is now not available.
Currently, I have these solutions in mind:
- Export my plugin store object to index.js main app, and use this store as a module.
- Use some other state management.
Is there a way to use Vuex inside my plugin?
https://codesandbox.io/s/vibrant-sanne-67yej?file=/src/main.js:0-371
CodePudding user response:
Vuex plugin uses store option to assign store instance to Vue.prototype.$store, similarly to your own plugin.
If the intention is to use multiple stores, their names shouldn't collide. The key is to name your store object inside plugin something other than $store
Vue.prototype.$myPluginStore = storeInstance;
But this still doesn't encapsulate $myPluginStore inside the plugin, as it is accessible within the app.
// App.vue
computed: {
appState() {
return this.$store.state;
},
pluginState() {
return this.$myPluginStore.state; // this is now accessible within the main app
}
}
It would be a reasonable solution to allow a store to be used as a module of existing store instead of creating a new store, but only when used within one app and not when used as a plugin for a package.
The main problem is that default store instance ($store) can make use of Vuex helpers - mapGetters, etc.
CodePudding user response:
You can take advantage of the install method exposed by the plugin to get access to the store - which should be accessible from your other component.
One possible solution is to register your store in the index.js like:
import Vue from "vue";
import App from "./App.vue";
import store from "./store";
import plugin from "./plugin";
Vue.use(plugin);
new Vue({
store,
components: {
App
}
}).$mount("#app");
You can then expose $doStuff() and get access to $store in the plugin.js
export default {
install(Vue) {
Vue.prototype.$doStuff = function (payload) {
this.$store.dispatch("SOME_RANDOM_ACTION", payload);
};
}
};
The store instance is accessible from your plugin or all the other components.
You can see a working sample here
