可以在 Vuex 状态下使用 Javascript 类对象吗?

cor*_*ory 11 vuex

假设我有一个简单的 Vuex 状态来保存食谱:

const state = {
    recipe: {
        id: '',
        name: "",
        ingredients : [],
    }
};
Run Code Online (Sandbox Code Playgroud)

而是创建一个包含相同数据的配方类,然后在状态中将其声明为该类的实例是一种好习惯吗?

const state = {
    recipe: new Recipe()
};
Run Code Online (Sandbox Code Playgroud)

如果配方类有方法,这些方法应该通过 vuex 存储上的 getter/mutations 来代理,还是可以直接调用这些方法?

Mar*_*cel 2

虽然我不能给出权威的答案,但我会说是的,你应该使用该州的课程。我认为这种良好的做法符合关注点分离设计原则。但是,您不应该在这些类上有可以直接调用的方法。

太长;博士;

  • 使用类作为 DTO 或模型
  • 保持方法的状态干净,但如果需要,您可以添加一些“本地计算的状态”。
  • 在突变中根据需要对数据进行突变,如果需要,甚至可以从上面突变一些“本地计算的状态”。
  • 如果需要,选择具有特定 getter 的特定数据,可能对相同的基础数据有许多 getter
  • 如果需要,在状态、getter 和mutations 之外实现单独的代码,而不是直接在其中实现方法。

例子

在我的应用程序中,使用vuextypescript,我编写了一个“api-model”,它表示 API 响应和请求的各个部分,以及一些作为unitTree.ts帮助器类代码,负责处理enterpriseUnitsTree状态部分,即的本地子集caseFullData

这是我在 state.ts 中执行此操作的方法(简化):

import { ICaseFullDataViewModel, CaseFullDataViewModel, CaseApprovalDto, ICaseApprovalDto } from '@/api-model';
import { IEnterpriseUnitDataObjectTree } from '../code/unitTree';

export interface IEntryState {
    caseValidationMessages: string[];
    caseFullData: ICaseFullDataViewModel;
    enterpriseUnitsTree: Array<IEnterpriseUnitDataObjectTree>;
    caseApproval: ICaseApprovalDto;
}

export const state: IEntryState = {
    caseValidationMessages: null,
    caseFullData: new CaseFullDataViewModel(),
    enterpriseUnitsTree: null,
    caseApproval: new CaseApprovalDto()
};
Run Code Online (Sandbox Code Playgroud)

至于获取数据,我建议为您需要的每个方面准备一套完整的 getter。它保持状态干净,因为实际上只是一个状态,而不是业务/用例本身。有关上述部分数据,请参阅下面的一些 getter。例如,我使用外部代码从商店中unitTree.ts提取特定项目。enterpriseUnitsTree

这是我在 getters.ts 中的代码(简化):

import { IRootState } from '@/store';
import { GetterTree } from 'vuex';
import { unitTree } from '../code/unitTree';
import { IEntryState } from './state';

export const CASE_ID = 'caseId';
export const CASE_FULL_DATA = 'caseFullData';
export const UNITS_SORTED_AS_TREE = 'unitsSortedAsTree';
export const FIRST_UNIT = 'firstUnit';


export const getters: GetterTree<IEntryState, IRootState> = {
    [CASE_ID]: state => state.caseFullData?.caseId,  
    [CASE_FULL_DATA]: state => state.caseFullData,
    [UNITS_SORTED_AS_TREE]: state => {
        return state.enterpriseUnitsTree;
    },
    [FIRST_UNIT]: state => () => {        
        const indexMap = unitTree.getIndexMap(state.enterpriseUnitsTree);
        const firstUnitIdentifier = indexMap.get(0);        
        return firstUnitIdentifier;
    }
    //.... 
};
Run Code Online (Sandbox Code Playgroud)

在 中,当收到相应数据的提交时,mutations.ts我会根据需要更改:enterpriseUnitsTree

这是我在mutations.ts中的代码(简化):

import { MutationTree } from 'vuex';
import {
    ICaseFullDataViewModel    
} from '@/api-viewmodel';
import { IEntryState } from './state';
import { unitTree } from '../code/unitTree';

export const MAPCASEFULLDATA = 'mapCaseFullData';
//....

export const mutations: MutationTree<IEntryState> = {
    [MAPCASEFULLDATA](state, value: ICaseFullDataViewModel) {
        state.caseFullData = value;
        //... some sorting and tree building using code from unitTree
        state.enterpriseUnitsTree = sortedEnterpriseUnits;
    },
    //.......
};
Run Code Online (Sandbox Code Playgroud)