Vuex rompt l'encapsulation

Lorsque mon projet Vue a commencé à s'étendre et a atteint plusieurs centaines de composants, j'ai pensé à l'approche de Vue et Vuex à l'architecture du projet.



J'ai commencé à utiliser Vue dans mes projets il y a environ 3 ans. Ensuite, j'ai utilisé du js pur pour écrire du code et j'ai cru que js n'était que dans le frontend, et NodeJs n'était pas adapté aux gros projets, mais j'avais tort ...


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