티스토리 뷰

Library | Framework/Vue JS

[Vue.js] 19. Vuex

공부하는 승승 2023. 8. 7. 02:23

Vuex

: 사용 이유

props, custom event로 데이터를 주고받으면 컴포넌트가 여러개일 때 관리하기가 힘듦

(컴포넌트, 데이터 개수가 적을 때는 props가 더 나을 수 있음)

 

1. 설치

npm install vuex@next

 

2. 세팅

  • src폴더 > store.js 파일 생성
// store.js
import { createStore } from 'vuex';

const store = createStore({
    state() {
        return {
            name: 'kim', // 보관하고 싶은 state(:데이터)
        };
    },
});

export default store;

 

  • main.js에 store파일 import
// main.js
import { createApp } from 'vue';
import App from './App.vue';
let app = createApp(App);

import store from './store';

app.use(store).mount('#app'); // 모든 컴포넌트들이 이 store 안에 있는 state(:데이터)들을 공유

 

3. 사용하기

{{ $store.state.state이름 }}

 

  • ex)
{{ $store.state.name }}

 

❗ Vuex 컴포넌트 안에서 직접 수정 금지

 

 

4. state 변경하기1 - mutations(순차적으로 state변경)

  1. 미리 store.js에 수정방법을 정의
  2. 해당 방법을 컴포넌트에서 소환해서 수정
// store.js
import { createStore } from 'vuex';

const store = createStore({
    state() {
        return {
            name: 'kim',
            age: 20,
        };
    },
    mutations: { // 순차적으로 state 변경
        updateName(state) {
            state.name = 'park';
        },
        addAge(state, payload) {
            state.age += payload;
        },
    },
});

export default store;
<!-- App.vue -->
<template>
    <div class="header">
        <h4>안녕 {{ $store.state.name }}</h4>
        <button @click="$store.commit('updateName')">이름변경</button>
        
        <span>{{ $store.state.age }}</span>
        <button @click="$store.commit('addAge', 3)">나이추가</button> <!-- age + 3 -->
    </div>
</template>

 

 

5. state 변경하기2 -  actions(ajax, 오래걸리는작업)

// store.js
import axios from 'axios';
import { createStore } from 'vuex';

const store = createStore({
    // 보관하고 싶은 state(:데이터)
    state() {
        return {
            name: 'kim',
            age: 20,
            likes: 0,
            clickLikes: false,
            more: {},
        };
    },
    // 순차적으로 state 변경
    mutations: {
        ...
        setMore(state, data) {
            state.more = data;
        },
    },
    // ajax, 오래걸리는 작업
    actions: {
        getData(context) {
            axios
                .get(`https://codingapple1.github.io/vue/more0.json`)
                .then((res) => {
                    context.commit('setMore', res.data);
                })
                .catch((err) => console.log(err));
        },
    },
});

export default store;
<!-- App.vue -->
<template>
    <p>{{ $store.state.more }}</p>
    <!-- dispatch: actions요청 -->
    <button @click="$store.dispatch('getData')">더보기</button>
</template>

 

 

6. computed 함수

  • methods 함수: 사용할 때마다 실행
  • computed 함수: 사용해도 실행되지 않음.처음 실행할 때 값을 간직함 - 데이터 결과 저장소...
<!-- App.vue -->
<template>
    <div>
        <p>{{ now() }}{{ counter }}</p> <!-- methods -->
        <p>{{ now2 }}{{ counter }}</p>  <!-- computed -->
        <button @click="counter++">버튼</button>
    </div>
</template>

<script>
export default {
    name: 'App',
    data() {
        return {
            counter: 0,
        };
    },
    methods: {
        now() {
            return new Date();
        },
    },
    computed: {
        now2() {
            return new Date();
        },
    },
};
</script>

 

 

 

7. mapState

  • store에 저장한 state 편하게 꺼내 쓰기
// store.js
import axios from 'axios';
import { createStore } from 'vuex';

const store = createStore({
    state() {
        return {
            name: 'kim',
            age: 20,
            likes: 0,
            clickLikes: false,
            more: {},
        };
    },
    mutations: {
        updateName(state) {
            state.name = 'park';
        },
        addAge(state, payload) {
            state.age += payload;
        },
        likes(state) {
            if (!state.clickLikes) {
                state.likes++;
                state.clickLikes = true;
            } else {
                state.likes--;
                state.clickLikes = false;
            }
        },
        setMore(state, data) {
            state.more = data;
        },
    },
    actions: {
        getData(context) {
            axios
                .get(`https://codingapple1.github.io/vue/more0.json`)
                .then((res) => {
                    console.log(res.data);
                    context.commit('setMore', res.data);
                })
                .catch((err) => console.log(err));
        },
    },
});

export default store;
<template>
    <div>
        <!-- mapState 사용 -->
        {{ name }} {{ age }} {{ likes }}
        {{ 내이름 }}
        
        <button @click="$store.commit('addAge', 3)">나이+</button> <!-- mapState 사용x -->
        <button @click="addAge(3)">나이+3</button> <!-- mapState 사용o -->
    </div>
</template>

<script>
import { mapActions, mapMutations, mapState } from 'vuex';

export default {
    name: 'App',
    data() {
        return {
            postData: postData,
            moreCount: 0,
            step: 0,
            image: '',
            writePost: '',
            selectedFilter: '',
            counter: 0,
        };
    },
    methods: {
        ...mapMutations(['addAge', 'likes', 'setMore']),
        ...mapActions(['getData']),
       ...
    },
    computed: {
        ...
        ...mapState(['name', 'age', 'likes']),
        ...mapState({ 내이름: 'name' }),
    },
};
</script>

 

'Library | Framework > Vue JS' 카테고리의 다른 글

[Vue.js] 21. Composition API  (0) 2023.08.07
[Vue] 20. PWA  (0) 2023.08.07
[Vue.js] 18. mitt  (0) 2023.08.07
[Vue.js] 17. slot  (0) 2023.08.07
[Vue.js] 16. 서버없이 이미지 업로드  (0) 2023.08.06
댓글