vuex 스토어 구조화에 대한 대안적 접근

16233 단어 vuejavascriptvuex
vuex를 사용하여 충분히 큰 Vue 프로젝트의 상태를 관리할 때 때로는 관리하기 어려울 수 있으며, 모듈을 사용할 때는 더욱 그렇습니다. 전달되는 작업은 네임스페이스 문자열입니다. 저장소의 상태에 액세스하는 것은 때때로 지저분할 수 있습니다(게터는 때때로 눈살을 찌푸립니다). 또한 비즈니스 로직은 "액션"또는 "돌연변이"(또는 "게터")에 있어야 합니까?
vuex 매장 관리에 합리적인 접근 방식을 추가하기 위해 제안 사항이 있습니다.


모듈, 네임스페이스 없음



먼저 폴더 구조를 빠르게 살펴보겠습니다. /store/modules 폴더로 구성되며, 이 폴더는 다른 상태의 하위 집합을 호스팅합니다.

그러면 각 모듈에는 폴더(예: store/modules/user )가 있으며 그 안에는 actions.js , getters.js , mutations.js , state.js , types.js (나중에 자세히 설명), 마지막으로index.js 모든 것을 함께 묶습니다.

보다 일반적인 설정과의 주요 차이점은 이름 공간을 사용하지 않는다는 것입니다. 이렇게 하면 이 접근 방식의 초점인 유형이 손상될 수 있기 때문입니다.


게터만, 단일 돌연변이



그러나 유형을 살펴보기 전에 이 접근 방식의 또 다른 규칙은 getters를 사용하여 저장소 상태에 액세스하는 것입니다. 모든 게터가 상태의 필드를 반환하는 것이라면 이것은 과잉으로 들릴 수 있지만 이 접근 방식은 저장소 액세스에 일관성을 가져오고 실제로는 짐작할 수 있듯이 유형과 함께 빛날 것입니다!

단순함을 위해 다음과 같이 각 모듈에 대해 단일 변형만 정의합니다.
mutations.js
const mutations = {
  update(state, { key, value }) {
    state[key] = value;
  },
};

export default mutations;



모든 유형



개인적인 취향일 수도 있지만 저는 특히 코드 전체에 손으로 쓴 문자열을 사용하는 것을 싫어합니다. 첫째, 오타는 매우 쉽게 만들어지고 정적 분석 도구(예: ESLint)는 실제로 도움이 되지 않습니다. 또한 특정 작업 또는 getter의 이름이 어떻게 지정되었는지 기억해야 하며 이는 대규모 코드베이스에서 작업하고 팀의 일원이 될 때 추적하기 어려울 수 있습니다.

이러한 이유로 이 전체 접근 방식은 문자열 대신 상수 변수를 사용하는 것을 기반으로 합니다. redux 세계에서 본 것과 유사하게 action, getter 및 key에 대한 유형을 정의할 것입니다(나중에 돌연변이에 대해 자세히 설명).

실제로 이는 다음과 같은 유형을 정의하는 것을 의미합니다.
types.js
export const USER_GETTER_CURRENT = "g/user/current";
export const USER_GETTER_FEED = "g/user/feed";
export const USER_GETTER_OVERVIEW = "g/user/overview";

export const USER_ACTION_GET_CURRENT = "a/user/getCurrent";
export const USER_ACTION_GET_FEED = "a/user/getFeed";
export const USER_ACTION_GET_OVERVIEW = "a/user/getOverview";

export const USER_KEY_CURRENT = "k/user/current";
export const USER_KEY_FEED = "k/user/feed";
export const USER_KEY_OVERVIEW = "k/user/overview";
export const USER_KEY_DETAILS = "k/user/details";


그런 다음 모듈의 다른 파일에서 다음과 같이 사용됩니다.actions.js
import api from "@/api";

import {
  USER_ACTION_GET_CURRENT,
  USER_ACTION_GET_FEED,
  USER_ACTION_GET_OVERVIEW,
  USER_KEY_CURRENT,
  USER_KEY_FEED,
  USER_KEY_OVERVIEW,
} from "@/store/types";

const actions = {
  [USER_ACTION_GET_CURRENT]({ commit }) {
    return api.get(`/user`).then((res) => {
      commit("update", { key: USER_KEY_CURRENT, value: res.data });
    });
  },
  [USER_ACTION_GET_FEED]({ commit }) {
    return api.get(`/feed`).then((res) => {
      commit("update", { key: USER_KEY_FEED, value: res.data });
    });
  },
  [USER_ACTION_GET_OVERVIEW]({ commit }) {
    return api.get(`/overview`).then((res) => {
      commit("update", { key: USER_KEY_OVERVIEW, value: res.data });
    });
  },
};

export default actions;

getters.js
import {
  USER_GETTER_CURRENT,
  USER_GETTER_FEED,
  USER_GETTER_OVERVIEW,
  USER_KEY_CURRENT,
  USER_KEY_FEED,
  USER_KEY_OVERVIEW,
} from "@/store/types";

const getters = {
  [USER_GETTER_CURRENT](state) {
    return state[USER_KEY_CURRENT];
  },
  [USER_GETTER_FEED](state) {
    return state[USER_KEY_FEED];
  },
  [USER_GETTER_OVERVIEW](state) {
    return state[USER_KEY_OVERVIEW];
  },
};

export default getters;

state.js
import {
  USER_KEY_CURRENT,
  USER_KEY_FEED,
  USER_KEY_OVERVIEW,
  USER_KEY_DETAILS,
} from "@/store/types";

const state = () => ({
  [USER_KEY_CURRENT]: {},
  [USER_KEY_FEED]: [],
  [USER_KEY_OVERVIEW]: [],
  [USER_KEY_DETAILS]: {},
});

export default state;


이것은 틀림없이 사소한 문제에 대해 많은 추가 장황한 것처럼 보일 수 있지만 구성 요소에서 저장소와 상호 작용할 때 이 접근 방식이 실제로 빛을 발하므로 저를 고수하십시오!


행복한 구성 요소



마침내, 이 모든 노력이 우리를 결실로 이끕니다!

요약하면 다음 지침에 따라 vuex 매장을 구축했습니다.
  • 모듈, 네임스페이스 없음
  • 게터만, 단일 돌연변이
  • 모든 유형

  • 이제 구성 요소에서 이것을 어떻게 사용할 수 있는지, 그리고 이 접근 방식의 주요 이점을 살펴보겠습니다.
    App.vue
    <template>
      ...
    </template>
    
    <script>
    import { computed, ref } from "vue";
    import { useStore } from "vuex";
    
    import {
      USER_ACTION_GET_CURRENT,
      USER_GETTER_CURRENT,
    } from "@/store/types";
    
    ...
    
    export default {
      components: {
        ...
      },
      setup() {
        const store = useStore();
        store.dispatch({ type: USER_ACTION_GET_CURRENT });
    
        ...
    
        const user = computed(() => store.getters[USER_GETTER_CURRENT]);
    
        ...
    
        return {
          ...
        };
      },
    };
    </script>
    


    여기에서 이미 이 접근 방식의 모든 이점을 볼 수 있습니다.
  • ESLint와 같은 정적 분석 도구를 사용하는 경우 유형을 작성하지 않을 것이라는 강력한 보장을 받습니다(일부 IDE에서는 자동 완성 기능도 제공됨).
  • 구성 요소가 전달할 수 있는 작업을 한 눈에 볼 수 있으며 getter를 통해서만 상태에 액세스할 수 있으므로 액세스 중인 데이터도 한 눈에 볼 수 있습니다.



  • 그래서, 당신은 그것을 가지고 있습니다. 이 모든 비트를 하나로 묶기 위해 더 많은 타격과 휘파람이 있지만 이것이 핵심입니다.
    vuex 응용 프로그램의 상태를 관리하기 위해 Vue를 사용한 경험에서 얻을 수 있는 피드백도 자유롭게 공유하십시오.

    좋은 웹페이지 즐겨찾기