Vue 6일차

진창호·2023년 5월 15일
0

Vue

목록 보기
6/6

Vue는 Vuex를 지원한다.

Vuex는 Vue.js app에 대한 상태관리패턴 + 라이브러리이다.

Vuex를 사용하면 컴포넌트 간 통신을 아래와 같이 수행할 수 있다.

Vue의 핵심 구성요소는 아래와 같다.

Actions의 의미는 아래와 같다.

Mutations의 의미는 아래와 같다.

State의 의미는 아래와 같다.

State가 변했을 때 출력되는 화면을 변하게 하기 위해서 Getters를 쓴다.
Getters의 의미는 아래와 같다.

원래는 아래와 같이 컴포넌트 통신을 해야 한다.

// Step00View.vue

<template>
  <div class="text-center">
    <h2>당신이 좋아하는 파트를 선택하세요</h2>
    <result-component :total="count" />
    <subject-component @add-tot-count="addTotalCount" title="코딩"></subject-component>
    <subject-component @add-tot-count="addTotalCount" title="알고리즘"></subject-component>
  </div>
</template>

<script>
import ResultComponent from "@/components/step00/ResultComponent";
import SubjectComponent from "@/components/step00/SubjectComponent";

export default {
  data() {
    return {
      count: 0,
    };
  },
  components: {
    ResultComponent,
    SubjectComponent,
  },
  methods: {
    addTotalCount() {
      this.count += 1;
    },
  },
};
</script>
<style scoped>
.text-center {
  text-align: center;
}
</style>
// ResultComponent.vue

<template>
  <h2>{{ total }}</h2>
</template>

<script>
export default {
  // props: ["total"],
  computed: {
    total() {
      return this.$store.state.count;
    },
  },
};
</script>

<style></style>
// SubjectComponent.vue

<template>
  <button @click="addCount">{{ title }} - {{ count }}</button>
</template>

<script>
export default {
  name: "SubjectComponent",
  props: ["title"],
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    addCount: function () {
      this.count += 1;
      // this.$emit("addtotcount");
      this.$store.state.count++;
    },
  },
};
</script>

<style></style>

하지만 Vuex를 쓰면 아래와 같이 컴포넌트 통신을 할 수 있다.

// store/index.js

export default new Vuex.Store({
  state: {
    count: 0,
  },
  actions: {
    asyncAddOne(context) { // 첫번째 인자로 context가 자동 주입
      setTimeout(() => {
        context.commit("addOne");
      }, 2000);
    },
  },
  mutations: {
    ADD_ONE(state) { // 첫번째 인자로 state가 자동 주입
      state.count += 1;
    },
    ADD_TEN_COUNT(state, payload) {
      state.count += payload;
    },
    ADD_OBJ_COUNT(state, payload) {
      state.count += payload.num;
    },
  },
  getters: {
    // 복잡한 계산식을 처리 : computed
    countMsg(state) { // 첫번째 인자로 state가 자동 주입
      let msg = "10번보다 ";
      if (state.count > 10) {
        msg += "많이 ";
      } else {
        msg += "적게 ";
      }
      return msg + " 호출됨(" + state.count + ")";
    },
  },
});
// Step07View.vue

<template>
  <div class="text-center">
    <h2>당신이 좋아하는 파트를 선택하세요</h2>
    <result-component />
    <subject-component title="코딩"></subject-component>
    <subject-component title="알고리즘"></subject-component>
  </div>
</template>

<script>
import ResultComponent from "@/components/step07/ResultComponent";
import SubjectComponent from "@/components/step07/SubjectComponent";

export default {
  components: {
    ResultComponent,
    SubjectComponent,
  },
};
</script>
<style>
.text-center {
  text-align: center;
}
</style>	
// ResultComponent.vue

<template>
  <div>
    <h2>{{ total }}</h2>
    <h2>{{ countMsg }}</h2>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
export default {
  computed: {
    // countMsg() {
    //   return this.$store.getters.countMsg;
    // },
    ...mapGetters(["countMsg"]),

    total() {
      return this.$store.state.count;
    },
  },
};
</script>

<style></style>
// SubjectComponent.vue

<template>
  <div>
    <button @click="addCount">{{ title }} - {{ count }}</button>
    <button @click="addTenCount">{{ title }} - {{ count }}</button>
    <button @click="addObjCount">{{ title }} - {{ count }}</button>
    <button @click="asyncCount">Action {{ title }} - {{ count }}</button>
  </div>
</template>

<script>
import { mapMutations, mapActions } from "vuex";
export default {
  name: "SubjectComponent",
  props: ["title"],
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    ...mapMutations({
      addMOne: "ADD_ONE",
      addMTenCount: "ADD_TEN_COUNT",
      addMObjCount: "ADD_OBJ_COUNT",
    }),
    ...mapActions(["asyncAddOne"]),
    addCount: function () {
      this.count += 1;
      // this.$store.commit('addOne');
      this.addMOne();
    },
    addTenCount: function () {
      this.count += 10;
      // this.$store.commit('addCount', 10);
      this.addMTenCount(10);
    },
    addObjCount: function () {
      let num = Math.round(Math.random() * 100);
      this.count += num;
      // this.$store.commit('addObjCount', { num });
      this.addMObjCount({ num });
    },
    asyncCount() {
      // this.$store.dispatch("asyncAddOne");
      this.asyncAddOne();
    },
  },
};
</script>

<style></style>
profile
백엔드 개발자

0개의 댓글