vuex-class-module
Version:
A library offering syntatic sugar to help declare vuex modules using JavaScript ES6 classes
101 lines (87 loc) • 2.62 kB
text/typescript
export type VuexModule = {
namespaced: boolean,
state?: any,
mutations?: any,
actions?: any,
getters?: any,
modules?: any,
}
const store:any = {}
export function VuexClass(options:{ modules: {} }) {
return function ( target:any ) {
const ModuleClass = target
const name = getNameFromClass( ModuleClass );
if( nameIsNotFound( name ) ) {
initializeStore( name );
}
assignState( ModuleClass, name );
assignModules( options.modules, name );
}
}
export function Mutation( target:any, key:string, descriptor:object ) {
const name = getNameFromTarget( target );
if( nameIsNotFound(name) ) {
initializeStore( name );
}
store[ name ].mutations[ key ] = target[ key ];
}
export function Action( target:any, key:string, descriptor:object ) {
const name = getNameFromTarget( target );
if( nameIsNotFound(name) ) {
initializeStore( name );
}
store[ name ].actions[ key ] = target[ key ];
}
export function Getter( target:any, key:string, descriptor:object) {
const name = getNameFromTarget( target );
if( nameIsNotFound(name) ) {
initializeStore(name);
}
store[ name ].getters[ key ] = target[ key ];
}
export function HasGetter( target:any, propertyKey:string) {
const name = getNameFromTarget( target );
if( nameIsNotFound(name) ) {
initializeStore(name);
}
store[ name ].getters[propertyKey] = function(state:any) {
return state[ propertyKey ];
}
}
export function extractVuexModule( ModuleClass:any ): VuexModule {
const name = ModuleClass.name;
return store[ name ];
}
function assignState( ModuleClass:any, moduleName?:string ) {
let vModule = store[ moduleName ];
const classModule = new ModuleClass();
const allProps = Object.getOwnPropertyNames( classModule );
allProps.forEach( function( prop) {
if( prop == moduleName ) return;
vModule.state[ prop ] = classModule[ prop ];
})
}
function assignModules( modules:object, moduleName:string ) {
store[ moduleName ].modules = modules;
}
function initializeStore( name: string ): VuexModule {
const vmodule = {
namespaced: true,
state: {},
mutations: {},
actions: {},
getters: {},
modules: {},
};
store[ name ] = vmodule;
return store[ name ];
}
function getNameFromTarget( target:any ):string {
return target.constructor.name;
}
function getNameFromClass( Class:any ): string {
return Class.name;
}
function nameIsNotFound( name: string ): boolean {
return store[ name ] == undefined;
}