Vuex unterbricht die Kapselung

Als mein Vue-Projekt zu erweitern begann und mehrere hundert Komponenten erreichte, dachte ich über den Ansatz von Vue und Vuex in Bezug auf die Projektarchitektur nach.



Ich habe vor ungefähr 3 Jahren angefangen, Vue in meinen Projekten zu verwenden. Dann habe ich reines js verwendet, um Code zu schreiben, und geglaubt, dass js nur im Frontend ist und NodeJs nicht für große Projekte geeignet ist, aber ich habe mich geirrt ...


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