14 Vuex - 프로젝트 구조화 및 모듈화

source: categories/study/vue-beginner-lv2/vue-beginner-lv2_9-05.md

14.1 스토어 속성 모듈화 방법

프로젝트 구조화와 모듈화 방법 1

  • 아래와 같은 store 구조를 어떻게 모듈화할 수 있을까?
// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {},
    getters: {},
    mutations: {},
    actions: {}
})

힌트! Vuex.Store({})의 속성을 모듈로 연결

  • ES6의 import & Export를 이용하여 속성별로 모듈화
import Vue from 'vue';
import Vuex from 'vuex';
import * as getters from 'store/getters.js';
import * as mutations from 'store/mutations.js';
import * as actions from 'store/actions.js';

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {},
    getters: getters,
    mutations: mutations,
    actions: actions
})

src/store/store.js

// store.js
import Vue from "vue";
import Vuex from "vuex";
import * as getters from "@/store/getters";
import * as mutations from "@/store/mutations";

// vue 플러그인을 사용하는 코드
// use는 vue의 플러그인을 등록하는 기능을한다.
// use를 쓰는 이유는 일반적으로 vue를 사용할 때, 전역으로.. 그러니가 vue를 사용하는 모든 영역에 특정 기능을 추가하고 싶을 때,
// 글로벌 펑셔널리티를 추가하고싶을 때, 사용합니다.
Vue.use(Vuex);

const storage = {
    fetch() {
        const arr = [];
        if (localStorage.length > 0) {
            for (let i=0; i < localStorage.length; i++) {
                if (localStorage.key(i) !== 'loglevel:webpack-dev-server') {
                    arr.push(JSON.parse(localStorage.getItem(localStorage.key(i))));
                }
            }
        }
        return arr;
    }
}

export const store = new Vuex.Store({
    state: {
        todoItems: storage.fetch()
    },
    getters,
    mutations,
});

// 간단한 설치와함께 Vuex 등록까지 마친상태

src/store/getters.js

const storedTodoItems = (state) => {
    return state.todoItems;
}

export {storedTodoItems}

src/store/mutations.js

const addOneItem = (state, todoItem) => {
    const obj = {completed: false, item: todoItem};
    localStorage.setItem(todoItem, JSON.stringify(obj));
    state.todoItems.push(obj);
}
const removeOneItem = (state, {todoItem, index}) => {
    localStorage.removeItem(todoItem.item);
    state.todoItems.splice(index, 1);
}
const toggleOneItem = (state, {todoItem, index}) => {
    state.todoItems[index].completed = !state.todoItems[index].completed;
    // todoItem.completed = !todoItem.completed; // deep copy를 해서 값을 변형시킨게 아니라 참조값을 변형시킨것이므로 todoItems 값에 변형이 가해진다.
    // 때문에 todoItems 값을 따로 업데이트 안해도된다. 그렇기 때문에 바로바로 화면 렌더링이 일어난다.
    localStorage.removeItem(todoItem.item); // 해당 키로 삭제
    localStorage.setItem(todoItem.item, JSON.stringify(todoItem)); // 키와 값 다시 재등록
}
const clearAllItems = (state) => {
    localStorage.clear();
    state.todoItems = [];
}

export {addOneItem, removeOneItem, toggleOneItem, clearAllItems}

14.2 스토어 모듈화 방법

프로젝트 구조화와 모듈화 방법 2

  • 앱이 비대해져서 1개의 store로는 관리가 힘들 때 modules 속성 사용
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
import todo from 'modules/todo.js';

Vue.use(Vuex);

export const store = new Vuex.Store({
    modules: {
        moduleA: todo, // 모듈 명칭 : 모듈 파일명
        todo // todo: todo
    }
})
// todo.js
const state: {}
const getters = {}
const mutations = {}
const actions = {}

src/store/store.js

import Vue from "vue";
import Vuex from "vuex";
import todoApp from "@/store/modules/todoApp";

Vue.use(Vuex);

export const store = new Vuex.Store({
    modules: {
        todoApp,
    }
});

src/store/modules/todoApp.js

const storage = {
    fetch() {
        const arr = [];
        if (localStorage.length > 0) {
            for (let i=0; i < localStorage.length; i++) {
                if (localStorage.key(i) !== 'loglevel:webpack-dev-server') {
                    arr.push(JSON.parse(localStorage.getItem(localStorage.key(i))));
                }
            }
        }
        return arr;
    }
}

const state = {
    todoItems: storage.fetch()
}

const getters = {
    storedTodoItems(state) {
        return state.todoItems;
    }
}

const mutations = {
    addOneItem(state, todoItem) {
        const obj = {completed: false, item: todoItem};
        localStorage.setItem(todoItem, JSON.stringify(obj));
        state.todoItems.push(obj);
    },
    removeOneItem(state, {todoItem, index}) {
        localStorage.removeItem(todoItem.item);
        state.todoItems.splice(index, 1);
    },
    toggleOneItem(state, {todoItem, index}) {
        state.todoItems[index].completed = !state.todoItems[index].completed;
        // todoItem.completed = !todoItem.completed; // deep copy를 해서 값을 변형시킨게 아니라 참조값을 변형시킨것이므로 todoItems 값에 변형이 가해진다.
        // 때문에 todoItems 값을 따로 업데이트 안해도된다. 그렇기 때문에 바로바로 화면 렌더링이 일어난다.
        localStorage.removeItem(todoItem.item); // 해당 키로 삭제
        localStorage.setItem(todoItem.item, JSON.stringify(todoItem)); // 키와 값 다시 재등록
    },
    clearAllItems(state) {
        localStorage.clear();
        state.todoItems = [];
    }
}

const actions = {

}

export default {
    state,
    getters,
    mutations,
    actions,
}