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

时间:2018-11-25 17:28:32

标签: vuex

让我们说我有一个简单的Vuex状态来保存食谱:

const state = {
    recipe: {
        id: '',
        name: "",
        ingredients : [],
    }
};

是否要创建一个保存相同数据的食谱类,然后在状态中将其声明为该类的实例,这是一种好习惯吗?

const state = {
    recipe: new Recipe()
};

如果食谱类具有方法,那么这些方法应该通过vuex存储上的getter / mutations进行代理,还是可以直接调用这些方法?

1 个答案:

答案 0 :(得分:1)

虽然我无法给出权威答案,但我会说是的,您应该在州内使用课程。我认为这种良好做法符合 Separation of Concern design principle。但是,您不应该在这些类上有直接调用的方法。

tl;博士;

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

示例

在我的应用程序中,使用 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()
};

至于获取数据,我建议为您需要的每个方面都有一套完整的 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;
    }
    //.... 
};

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;
    },
    //.......
};