Vuex quebra o encapsulamento

Quando meu projeto Vue começou a se expandir e alcançou várias centenas de componentes, pensei na abordagem de Vue e Vuex à arquitetura do projeto.



Comecei a usar o Vue em meus projetos há cerca de 3 anos. Então eu usei js puro para escrever código e acreditei que js é apenas no frontend, e os NodeJs não são adequados para grandes projetos, mas eu estava errado ...


Typescript.
, . typescript .


, js typescript , . , , , Vue.


Vuex:



, Vuex, , vuex , (SRP). Vuex " ". , , . SRP . ?


( , , — , - , ). . DI . , DI Service Locator .
, Vuex , Vuex.


Vuex vuex-smart-module :


class UserState {
    firstName: string = '';
    lastName: string = '';
}

class UserGetters extends Getters<UserState> {
    get fullName() {
        return this.state.firstName + ' ' + this.state.lastName;
    }
}

class UserMutations extends Mutations<UserState> {
    setFirstName(firstName: string) {
        this.state.firstName = firstName;
    }

    setLastName(lastName: string) {
        this.state.lastName = lastName;
    }
}

class UserActions extends Actions<
    UserState,
    UserGetters,
    UserMutations,
    UserActions
    > {
    async load() {
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve();
                this.mutations.setFirstName('FirstName');
                this.mutations.setLastName('LastName');
            }, 2000);
        });
    }
}

export const userStore = new Module({
    namespaced: true,
    state: UserState,
    getters: UserGetters,
    mutations: UserMutations,
    actions: UserActions
})

User ApiDatasource ( ):


class User {
    id: number;
    firstName: string;
    lastnName: string;

    constructor(props: {
        id: number;
        firstName: string;
        lastnName: string;
    }) {
        this.id = props.id;
        this.firstName = props.firstName;
        this.lastnName = props.lastnName;
    }
}

class ApiDatasource {
    async getCurrentUser(): Promise<User> {
        return new User({
            id: 0,
            firstName: 'Name',
            lastnName: 'Lear',
        });
    }
}

ApiDatasource ( , Vuex new Module)? , State ( , ).


UserState UserActions:


class UserState {
    firstName: string = '';
    lastName: string = '';
    apiDatasource: ApiDatasource | null = null;
}
class UserActions extends Actions<
    UserState,
    UserGetters,
    UserMutations,
    UserActions
    > {
    async load() {
        if (this.state.apiDatasource !== null) {
            let currUser = await this.state.apiDatasource.getCurrentUser();
            this.mutations.setFirstName(currUser.firstName);
            this.mutations.setLastName(currUser.lastName);
        }
    }
}

:


const UserStoreModuleName = 'user;'
export function registerUserStore(props: {
    apiDatasource: ApiDatasource;
    vuexStore: Store<any>;
}) {
    registerModule(props.vuexStore, [UserStoreModuleName], UserStoreModuleName, userStore);
    (props.vuexStore.state[UserStoreModuleName] as UserState).apiDatasource = props.apiDatasource;
}

(, , )
, props.vuexStore.state[UserStoreModuleName] . (props.vuexStore.state[UserStoreModuleName] as UserState). state vue, , .


. ? , commit, dispatch .
, :


store.dispatch('user/load')

( action mutation), , . .


Service Locator. Vue , vuex, action mutation . , action load user, ( , ), , . load. , , , IDE , .


. Vuex action. ? , - , action, vuex.


, vuex ( ) SRP, . , , vuex ? , vuex — vuex - Vue.


All Articles