// 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; } }; // store.js export default { actions: { SOME_RANDOM_ACTION({ state, commit }) { console.log("some random action"); } } };El envío de acciones y el uso del estado están bien y funcionan como se esperaba.
Pero cuando agrego este complemento a otra instancia de Vue que usa vuex, el objeto de la tienda se reinicializa con un nuevo estado.
// 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");Cuando elimina el comentario de la inicialización de la tienda, la tienda que se definió en el complemento ya no está disponible.
Actualmente, tengo estas soluciones en mente:
¿Hay alguna manera de usar Vuex dentro de mi complemento?
https://codesandbox.io/s/vibrant-sanne-67yej?file=/src/main.js:0-371
El complemento Vuex usa la opción de store para asignar la instancia de la tienda a Vue.prototype.$store , de manera similar a su propio complemento.
Si la intención es utilizar varias tiendas, sus nombres no deben coincidir. La clave es nombrar el objeto de su tienda dentro del complemento algo que no sea $store
Vue.prototype.$myPluginStore = storeInstance; Pero esto aún no encapsula $myPluginStore dentro del complemento, ya que es accesible dentro de la aplicación.
// App.vue computed: { appState() { return this.$store.state; }, pluginState() { return this.$myPluginStore.state; // this is now accessible within the main app } }Sería una solución razonable permitir que una tienda se use como un módulo de una tienda existente en lugar de crear una nueva tienda, pero solo cuando se usa dentro de una aplicación y no cuando se usa como un complemento para un paquete.
El principal problema es que la instancia de tienda predeterminada ( $store ) puede hacer uso de los ayudantes de Vuex: mapGetters , etc.
Puede aprovechar el método de instalación expuesto por el complemento para obtener acceso a la tienda, a la que debería poder acceder desde su otro componente.
Una posible solución es registrar su tienda en index.js como:
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"); Luego puede exponer $doStuff() y obtener acceso a $store en el plugin.js
export default { install(Vue) { Vue.prototype.$doStuff = function (payload) { this.$store.dispatch("SOME_RANDOM_ACTION", payload); }; } };Se puede acceder a la instancia de la tienda desde su complemento o desde todos los demás componentes.
Puede ver una muestra de trabajo aquí