Как правильно работать с Vuex и машинописью? - PullRequest
0 голосов
/ 17 декабря 2018

Пока единственная информация, которую я нашел по теме, была статья .

Я пытаюсь реализовать магазин с 2 модулями.

export interface RootState {
    /** root state props **/
}

const store: StoreOptions<RootState> = {
    modules: {
        foo,
        bar,
    },
};

export default new Vuex.Store<RootState>(store);

Тогда у меня есть оба модуля:

export interface FooState {
    //(...)    
}

export const foo: Module<FooState, RootState> = {
    //(...)
};

export interface BarState {
    //(...)    
}

export const bar: Module<BarState, RootState> = {
    //(...)
};

Все было в порядке, пока у меня не было одной ситуации, когда мне нужен был метод получения из модуля foo для доступа к состоянию панели:

export const getters: GetterTree<FooState, RootState> = {
    getInfo: (state, {}, rootState) => number {
        const value = rootState.bar.somevalue;
        //(...)
    },
};

У меня возникла ошибка, объясняющая, что rootState не имеет свойства bar.Поразмыслив об этом, мне удалось устранить ошибку, изменив исходный интерфейс RootState:

export interface RootState {
    /** root state props **/
    foo: FooState;
    bar: BarState;
}

Это решило проблему и отлично подошло для intellisense IDE.

Это правильный подход?Чтобы добавить все модули в интерфейс RootState, используемый StoreOptions?

Кроме того, как представляется, отсутствует документация об этих типизированных интерфейсах (StoreOptions, Module, GetterTree и т. Д.): Достаточно ли зрел Vuex для использованияс машинописным шрифтом?

Редактировать: я забыл упомянуть: мне все еще нужно привести это. $ store при доступе к хранилищу из компонента (но можно минимизировать его с помощью vuex-class ).Кажется, есть вопрос , открытый об этом без ответов.Я полагаю, что до сих пор нет другого решения, я прав?

1 Ответ

0 голосов
/ 15 июля 2019

В итоге я использовал пустой интерфейс rootState и динамически добавил все модули.Это устраняет проблему связи между модулями вообще.Позвольте мне объяснить, как.Я из C #, поэтому я хотел исключить строковые литералы и динамические типы.Я сделал это с vuex-typex .Обратите внимание, что это модуль, поэтому вы можете использовать множество пользовательских вещей, таких как события или вспомогательные функции.Вот мой упрощенный пример:

import { getStoreBuilder, BareActionContext } from "vuex-typex";
import { LiteEvent } from "./utility/LiteEvent";
import { IRootState } from "../store";
import ModuleApi, { IBuildInfo } from "./ModuleApi";

export interface IModuleState {
  builds: IBuildInfo[];
}

const moduleBuilder = getStoreBuilder<IRootState>().module<IModuleState >("branches", { builds: [] });

const buildsChanged: LiteEvent<void> = new LiteEvent<void>();

const ModuleStore = {
  get state(): IModuleState { return stateGetter(); },
  get lastBuildInfo(): IBuildInfo | null { return lastBuildInfoGetter(); },

  // mutations
  setBuilds: moduleBuilder.commit(setBuilds),

  // actions
  requestBuilds: moduleBuilder.dispatch(requestBuilds),

  buildsChanged: buildsChanged.expose(),
};
export default ModuleStore;

// getters
const stateGetter = moduleBuilder.state();

const lastBuildInfoGetter = moduleBuilder.read(lastBuildInfo);
function lastBuildInfo(state: IBranchesState): IBuildInfo | null {
  const len = state.builds.length;
  return len > 0 ? state.builds[state.builds.length - 1] : null;
}

// mutations
function setBuilds(state: IBranchesState, payload: { newBuilds: IBuildInfo[] }): void {
  state.builds = payload.newBuilds;
  onBuildsChanged.trigger();
}

type ActionContext = BareActionContext<IModuleState, IRootState>;

// actions
async function requestBuilds({ state }: ActionContext): Promise<void> {
  const builds = await RepoBrancesApi.getBuilds(state.currentBranch);
  BranchesStore.setBuilds({ newBuilds: builds});
}

getStoreBuilder<IRootState>().registerModule(moduleBuilder.namespace);

Если вас интересует LiteEvent - спасибо удивительным Пост Джейсона Клебана

Вот пример использования в другом модуле vuex или где-то ещееще:

async function requestSelectedChartGeom(context: ActionContext, payload: { chartName: string }): Promise<void> {
  const chartGeom = await ChartBoundApi.getBoundsForChart(ModuleStore.lastBuildInfo, payload.chartName);

  ...
}

ModuleStore.onBuildsChanged.on(s => {
  CommitLogStore.requestCommits();
});

Мне не очень нравится хранить код модуля (вы должны отделить определение getter / mutation / action от рабочей функции, потому что рабочая функция не должна быть анонимной), но нет динамическихтипы и строковые литералы, поэтому я счастлив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...