본문 바로가기
Vue.js 3.0

[Vue.js 3.0] vuex (3)

by 프갭 2023. 3. 21.

vuex 는 Vue.js애플리케이션에 대한 상태 관리 패턴 + 라이브러리 입니다.

모든 컴포넌트에 대한 중앙 집중식 저장소 역할

 

1)  설치 및 설정

https://eehnuyh.tistory.com/8 환경 설정을 Manually select features으로 진행 했을시 설치 항목은 넘어가도 됩니다.

 

1. PS D:\831228 EEH\EEH\EX\VUE\exui> npm i -save vuex

2. 폴더 및 store 파일 생성 (index.ts or index.js)

 

 

 

 

 

 

 

3.main.ts,main.js에 사용 선언

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';

createApp(App).use(store).use(router).mount('#app');
 

2)  src/store/index.ts (Vuex 기본 구조)

import { createStore } from 'vuex';
export default createStore({
    state: {},
    getters: {},
    mutations: {},
    actions: {},
    modules: {},
});

(1) state : 컴포넌트 간의 공유할 Data 속성 

index.ts

import { createStore } from 'vuex';

export default createStore({
    state: {
        count: 0,
    },
    getters: {},
    mutations: {},
    actions: {},
    modules: {},
});
 
 
<template>
    <div>count:{{ store.state.count }}</div>
</template>
<script lang="ts" setup>
import { useStore } from 'vuex';
const store = useStore();
</script>
 

(2) getters : 연산된 state값을 접근하는 속성

 
중앙 데이터 관리 구조에서 발생하는 문제중 하나는 각 컴포넌트에서  vuex 데이터 접근 할때 중복된 코드를 하게되는데 그런 비효율적인 코드를 vuex에 구현하여 가독성을 올리는 이점을 갖게 해준다.
 

index.ts

import { createStore } from 'vuex';


export default createStore({
    state: {
        count: 0,
    },
    getters: {
        getStringCount(state) {
            return '현재 카운트 값은 ' + state.count + '입니다.';
        },
    },
    mutations: {},
    actions: {},
    modules: {},
});
 
VuexView.vue
<template>
    <div>count:{{ store.state.count }}</div>
    <div>string count:{{ store.getters.getStringCount }}</div>
</template>
<script lang="ts" setup>
import { useStore } from 'vuex';
const store = useStore();
</script>
(3) mutations : state를 변경할 때 사용
 
state는 직접 변경할 수 없습니다. 그래서 핸들러 함수를 통해서 state를 변경해야 합니다. 즉, setter로 생각하시면 됩니다.
(commit 으로 호출 가능)
 
index.ts
import { createStore } from 'vuex';

export default createStore({
    state: {
        count: 0,
    },
    getters: {
        getStringCount(state) {
            return '현재 카운트 값은 ' + state.count + '입니다.';
        },
    },
    mutations: {
        setCount(state, val) {
            state.count = state.count + val;
        },
    },
    actions: {},
    modules: {},
});
 
VuexView.vue
<template>
    <div>count:{{ store.state.count }}</div>
    <div>string count:{{ store.getters.getStringCount }}</div>
    <input type="button" value="Add" @click="TestMutations" />
</template>
<script lang="ts" setup>
import { useStore } from 'vuex';
const store = useStore();
const TestMutations = () => {
    store.commit('setCount', 1);
};
</script>
 

(4) actions : mutations 에는 순차적인 로직(동기 방식) actions은 비순차적인 로직(비동기 방식)에 사용 된다.

mutations 는 state 값의 변화를 추적하기 어렵지만,actions는 변경 확인이 쉬어 비동기 방식에 사용된다.

(dispatch 으로 호출 가능)

index.ts

import { createStore } from 'vuex';

export default createStore({
    state: {
        count: 0,
    },
    getters: {
        getStringCount(state) {
            return '현재 카운트 값은 ' + state.count + '입니다.';
        },
    },
    mutations: {
        setCount(state, val) {
            state.count = state.count + val;
        },
    },
    actions: {
        setCountAsync(context, val) {
            setTimeout(() => {
                context.commit('setCount', val);
            }, 3000);
        },
    },
    modules: {},
});
VuexView.vue
<template>
    <div>count:{{ store.state.count }}</div>
    <div>string count:{{ store.getters.getStringCount }}</div>
    <input type="button" value="Add" @click="TestMutations" />
</template>
<script lang="ts" setup>
import { useStore } from 'vuex';
const store = useStore();
const TestMutations = () => {
    store.commit('setCount', 1);

    store.dispatch('setCountAsync', 1);
};
</script>
 
(5) modules : 규모가 큰 프로젝트인경우 사용되는 속성이나 상태 메서드가 많아진다 그럴때 모듈화하여 사용한다
서로 연관 있는 속성값끼리 병합하여 사용
폴더구조

index.ts

import { createStore } from 'vuex';
import { loginInfo, LoginState } from '@/store/modules/loginInfoModule';
import { settingInfo, SettingState } from '@/store/modules/settingModule';

 

export interface RootState {
    loginInfo: LoginState;
    settingInfo: SettingState;
}
export default createStore({
    modules: {
        loginInfo,
        settingInfo,
    },
});
 
loginInfoModule.ts
 
import { Module } from 'vuex';
import { RootState } from '@/store/index';
export interface LoginState {
    userName: string;
    email: string;
    id: number;
}
export const loginInfo: Module<LoginState, RootState> = {
    namespaced: true,
    state: {
        userName: '',
        email: '',
        id: 0,
    },
    getters: {
        getLoginInfo(state) {
            return state.userName + '(' + state.email + ')';
        },
        getAllInfo(state, getters, rootState, rootGetters) {
            return (
                state.userName +
                '|' +
                getters.getLoginInfo +
                '|' +
                rootState.loginInfo.userName +
                '|' +
                rootState.settingInfo.tag +
                '|' +
                rootGetters['loginInfo/getLoginInfo'] +
                '|' +
                rootGetters['settingInfo/getInfo']
            );
        },
    },
    mutations: {
        setLoginInfo(state, info) {
            state.userName = info.userName;
            state.email = info.email;
            state.id = info.id;
        },
    },
};
 
settingModule.ts
 
import { Module } from 'vuex';
import { RootState } from '@/store/index';
export interface SettingState {
    tag: string;
}
export const settingInfo: Module<SettingState, RootState> = {
    namespaced: true,
    state: {
        tag: 'setting',
    },
    getters: {
        getInfo(state) {
            return '현재 셋팅 정보는 ' + state.tag + '입니다.';
        },
    },
};
 
index.ts에는 분리된 모듈만 선언한다.
각 상태값 호출 방식이 변경된다
 
VuexView.vue
 
<template>
    <div>UserName:{{ store.state.loginInfo.userName }}</div>
    <div>string UserName:{{ store.getters['loginInfo/getLoginInfo'] }}</div>
    <div>string All:{{ store.getters['loginInfo/getAllInfo'] }}</div>
    <input type="button" value="Add" @click="TestMutations" />
</template>
<script lang="ts" setup>
import { useStore } from 'vuex';
import { LoginState } from '@/store/modules/loginInfoModule';

const store = useStore();
const TestMutations = () => {
    var l: LoginState = { userName: '테스트', email: 'test@test.com', id: 1 };
    store.commit('loginInfo/setLoginInfo', l);
};
</script>

 

 

반응형

'Vue.js 3.0' 카테고리의 다른 글

[Vue.js 3.0] Vue Router (2)  (0) 2023.03.21
[Vue.js 3.0] 환경 설정 및 프로젝트 생성 (1)  (0) 2023.03.16

댓글