@Ooos
Front-End

Можно ли использовать (а если можно то как) vuex внутри плагина для Vue?

К примеру я создаю плагин для vue, могу ли я использовать в плагине store (vuex)?
  • Вопрос задан
  • 579 просмотров
Решения вопроса 1
bingo347
@bingo347
Crazy on performance...
Тут есть несколько вариантов:

Вариант совсем плохой: тащим Vuex за своим плагином, сами подключаем, делаем свой store - профит. Плюс только один - просто реализовать. Плохо тем, что пользователь Вашего плагина не сможет взаимодействовать с его состоянием если захочет. Так же если Ваша версия Vuex будет отличаться от версии пользователя, то у пользователя в бандле vuex окажется 2 раза.

Вариант получше: жестко требуем у пользователя, чтоб он дал нам свой store в опциях к плагину, и инжектим в его store свой модуль. Можно так же указать vuex в peerDependencies нашего package.json
Плюсы: используем Vuex пользователя, а не тащим свой; даем пользователю взаимодействовать с состоянием плагина.
Минусы: засоряем store пользователя независимо от его желания; если пользователю не нужен store, он все равно будет вынужден его создать

Хороший вариант: даем пользователю опционально возможность отдать нам свой store, а если не дал - создаем свой.
Минус: заморочно в реализации
Плюс: свобода действий у пользователя, из обязательных действий - только установить Vuex

В любом случае лучше всего свое состояние держать в отдельном модуле Vuex
Почитать про модули можно тут: https://vuex.vuejs.org/ru/guide/modules.html

Ну и как реализовать хороший вариант, покажу на примере:
import Vuex from 'vuex';
import pluginStoreConfig from './store';

const PLUGIN_NAME = 'MyPlugin';
let Vue; // подключим из install

// наш плагин
export default {
  install(_Vue, options = {}) {
    Vue = _Vue;
    let {store} = options;
    if(store) {
      // если передали store - регистрируем в нем свой модуль
      store.registerModule(PLUGIN_NAME, pluginStoreConfig);
    } else {
      // не передали, для начала проверим, установлен ли Vuex в Vue
      if(!new Vue({store: {}}).$store) {
        // и если нет, установим
        Vue.use(Vuex);
      }
      // и создадим новый store с единственным модулем - нашим
      store = new Vuex.Store({modules: {
        [PLUGIN_NAME]: pluginStoreConfig
      }});
    }
    // немного упростим себе жизнь, чтоб не писать каждый раз наш нэймспейс
    // если что-то не используется, то можно убрать
    const boundStore = {
      state: store.state[PLUGIN_NAME],
      getters: store.getters[PLUGIN_NAME],
      commit(mutation, payload, options) {
        return store.commit(`${PLUGIN_NAME}/${mutation}`, payload, options);
      },
      dispatch(action, payload, options) {
        return store.dispatch(`${PLUGIN_NAME}/${action}`, payload, options);
      },
      watch(fn, cb, options) {
        return store.watch((state, getters) => fn(state[PLUGIN_NAME], getters[PLUGIN_NAME]), cb, options);
      }
    };
    // дальше творим прочую магию нашего плагина
    // ...
  }
};


Файл store.js будет почти обычным конфигом store, с одним исключением - работать он у нас будет в модуле, и ему нужен свой нэймспейс:
export default {
  namespaced: true,
  state: {/* ... */},
  getters: {/* ... */},
  actions: {/* ... */},
  mutations: {/* ... */}
};
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы