상세 컨텐츠

본문 제목

vuejs의 vuex를 이용한 Component간 데이터 동기화

개발

by Yo플레 2021. 1. 17. 19:40

본문

728x90
728x90

안녕하세요, Yo플레입니다.

오늘은 vuejs의 vuex를 이용한 Component간 데이터 동기화를 해보겠습니다.

vuejs를 개발하다보면 Component간의 데이터 동기화가 필요한 때가 있습니다.

vuex를 통해 데이터를 동기화하면 되는데, 어떤 이유에서인지 데이터가 동기화가 안되는 경우가 있습니다.

이럴 때는 데이터흐름을 살펴보는것이 좋습니다.

예제 보러 가기

App.vue

<template>
  <div id="app">
    <h1>Case1</h1>
    <CompA1 />
    <CompA2 />
    <h1>Case2</h1>
    <CompB1 />
    <CompB2 />
  </div>
</template>

<script>
import CompA1 from "./components/CompA1";
import CompA2 from "./components/CompA2";
import CompB1 from "./components/CompB1";
import CompB2 from "./components/CompB2";

export default {
  name: "App",
  components: {
    CompA1,
    CompA2,
    CompB1,
    CompB2,
  },
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

CompA1

<template>
  <div>
    <input type="text" v-model="text" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      text: "",
    };
  },
  computed: {
    getTextA() {
      return this.$store.getters.getTextA;
    },
  },
  watch: {
    getTextA() {
      this.text = this.getTextA;
    },
    text() {
      this.$store.commit("SET_TEXT_A", this.text);
    },
  },
};
</script>

CompA2

<template>
  <div>
    <input type="text" v-model="text" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      text: "",
    };
  },
  computed: {
    getTextA() {
      return this.$store.getters.getTextA;
    },
  },
  watch: {
    getTextA() {
      this.text = this.getTextA;
    },
    text() {
      this.$store.commit("SET_TEXT_A", this.text);
    },
  },
};
</script>

CompB1

<template>
  <div>
    <!-- <p>{{ text }}</p> -->
    <input type="text" v-model="text" @input="setText" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      text: "",
    };
  },
  computed: {
    textB() {
      return this.$store.getters.getTextB;
    },
  },
  watch: {
    textB() {
      this.text = this.textB;
    },
  },
  methods: {
    setText() {
      this.$store.commit("SET_TEXT_B", this.text);
    },
  },
};
</script>

CompB2

<template>
  <div>
    <!-- <p>{{ text }}</p> -->
    <input type="text" v-model="text" @input="setText" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      text: "",
    };
  },
  computed: {
    textB() {
      return this.$store.getters.getTextB;
    },
  },
  watch: {
    textB() {
      this.text = this.textB;
    },
  },
  methods: {
    setText() {
      this.$store.commit("SET_TEXT_B", this.text);
    },
  },
};
</script>

main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from "vue";
import App from "./App";
import store from "./store";

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: "#app",
  store,
  components: { App },
  template: "<App/>"
});

store.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    textA: "textA",
    textB: "textB"
  },
  getters: {
    getTextA(state) {
      return state.textA;
    },
    getTextB(state) {
      return state.textB;
    }
  },
  mutations: {
    SET_TEXT_A(state, payload) {
      state.textA = payload;
    },
    SET_TEXT_B(state, payload) {
      state.textB = payload;
    }
  },
  actions: {}
});

Case1의 CompA1, CompA2간의 데이터 흐름

  1. CompA1의 input을 수정
  2. CompA1의 watch의 text로 vuex에 데이터 전송
  3. CompA2의 computed의 getTextA로 vuex로부터 데이터 수신
  4. CompA2의 watch의 getTextA로 data의 text에 데이터 전달
  5. CompA2의 data의 text가 input에 표시

Case2의 CompB1, ComptB2간의 데이터 흐름

  1. CompB1의 input을 수정
  2. CompB1의 methods의 setText로 vuex에 데이터 전송
  3. CompB2의 computed의 textB로 vuex로부터 데이터 수신
  4. CompB2의 watch의 textB로 data의 text에 데이터 전달
  5. CompB2의 data의 text가 input에 표시

 

728x90

관련글 더보기

댓글 영역