vuex-relations v1.0.0
addStoreRelations
Функция позволяет накрутить хайтек в Vuex store такой, какой не снилось.
В проекте были встречены проблемы синхронизации actions и mutations между store модулями.
Так же был всякий ненужный бойлерплейт, как например подтягивание данных с сервера в created хуке компонента, регистрирующего store модуль.
В результате явилась миру эта функция.
arguments
Функция принимает как аргумент объект следующего вида:
interface IStoreMiddlewareVariables {
requiredRelations?: AvailableRelations | AvailableRelations[]
watchRelations?: IStoreRelationships
watchActions?: IStoreActionsSubscribe
moduleName: string
initDispatch: string
}
//, где
type WatchFunction = <T>(newValue: T, oldValue: T) => boolean
type ActionWatchFunction = (action: any, state: any) => boolean
interface IRelationDesc {
trigger: WatchFunction
dispatchFunc: string
}
interface IActionRelationDesc {
trigger?: ActionWatchFunction
dispatchFunc: string
beforeOrAfter?: 'before' | 'after' // по дефолту стоит 'after'
}
type AvailableRelations = 'currentClubId'
export interface IStoreRelationships {
[key: string]: IRelationDesc | undefined
}
export interface IStoreActionsSubscribe {
[key: string]: IActionRelationDesc
} moduleName- имяstoreмодуля, к которому подвяжутся зависимостиinitDispatch- имяaction, который запустится после создания экземпляра компонента, к которому привязанstoreмодуль. Сюда чаще всего идут запросы к серверу, по подтягиванию данных для таблиц и тд и тпrequiredRelations-state, который обязательно должен существовать, прежде чем запуститсяinitDispatchи все остальное, в случае, если этотstate, по какой-либо причине не будет существовать,initDispatchдождется его появления, прежде чем запустится. Пока что это все сделано только дляcurrentClubId, но если понадобится для чего-то ещё, то можно дописатьwatchRelations- триггеры, после которых нужно запустить функцию, переданную сюда в качестве аргументаdispatchFuncwatchActions-actions, после (или до) которых нужно запускатьdispatchFunc, переданную сюда в качестве аргумента
Пример
Пример использования в модуле "Герои и группы":
import { addStoreRelations } from '@/utils/helpers/vuexMiddleware'
import { getDefaultWatchTrigger } from '@/store/defaultWatchTriggers'
import { moduleName } from '@/views/App/Heroes/store/index'
addStoreRelations({
moduleName,
initDispatch: 'getOptions',
watchRelations: {
...getDefaultWatchTrigger('currentClubId', 'getOptions')
},
watchActions: {
'quickEditorChild/createChild': {
dispatchFunc: 'getOptions',
beforeOrAfter: 'after'
}
},
requiredRelations: 'currentClubId'
})Пример триггера на дефолтном триггере для currentClubId:
import { IStoreRelationships } from '@/utils/helpers/vuexMiddleware'
type WatchTriggers = 'currentClubId'
export const getDefaultWatchTrigger = (name: WatchTriggers, dispatchFunc: string): IStoreRelationships => {
return {
[name]: {
dispatchFunc,
trigger: (() => {
switch (name) {
case 'currentClubId':
return defaultCurrentClubIdTrigger
}
})()
}
}
}
export const defaultCurrentClubIdTrigger = (newValue: any, oldValue: any) => {
return newValue !== oldValue && !!newValue && !!oldValue
}В этом примере после создания основного компонента "Герои и группы", к которому привязан store, будет запущен action getOptions,
который подтягивает все необходимые данные с сервера, НО, getOptions дождется, пока currentClubId придет с сервера в state,
а уже потом подтянет все, что нужно.
После создания нового героя запустится action getOptions для обновления данных в таблице и тд.
И после смены клуба currentClubId администратором также запустится action getOptions, для обновления всех
необходимых данных для нового клуба.
В итоге получилась понятный переиспользуемый метод для подобных вещей.
6 years ago