<Do it! Vue.js ์ ๋ฌธ>์ ๊ธฐ๋ณธ์ผ๋ก ๋ฐฐ์ด ๋ด์ฉ์ ๋๋ค.
๋ชฉ์ฐจ
-
1. ์ํ ๊ด๋ฆฌ
-
2. Vuex
-
3. state
-
4. Getters & Mutations
-
5. Actions
-
6. Vuex ํฌํผ ํจ์ (mapGetters, mapMutations, mapActions )
์ฐธ๊ณ ํ ์ฌ์ดํธ
joshua1988.github.io/web-development/vuejs/vuex-start/
joshua1988.github.io/web-development/vuejs/vuex-getters-mutations/
joshua1988.github.io/web-development/vuejs/vuex-actions-modules/
1. ์ํ ๊ด๋ฆฌ
1-1) ์ํ ๊ด๋ฆฌ
์ํ ๊ด๋ฆฌ๋ ์ฌ๋ฌ ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ ์ ๋ฌ๊ณผ ์ด๋ฒคํธ ํต์ ์ ํ ๊ณณ์์ ๊ด๋ฆฌํ๋ ํจํด์ ์๋ฏธํ๋ค.
ํ๋ ์์ํฌ | ์ฌ์ฉํ๋ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ |
React | Redux/ Mobx |
Vue | Vuex |
1-2) ์ํ ๊ด๋ฆฌ ํจํด
- ์ํ : ์ฑ์ ์๋ํ๋ ์๋ณธ ์์ค
- ๋ทฐ : ์ํ์ ์ ์ธ์ ๋งคํ
- ์ก์ : ๋ทฐ์์ ์ฌ์ฉ์ ์ ๋ ฅ์ ๋ํด ๋ฐ์์ ์ผ๋ก ์ํ๋ฅผ ๋ฐ๊พธ๋ ๋ฐฉ๋ฒ
new Vue({
// ์ํ
data () {
return {
count: 0
}
},
// ๋ทฐ
template: `
<div>{{ count }}</div>
`,
// ์ก์
methods: {
increment () {
this.count++
}
}
})
1-3) ์ํ ๊ด๋ฆฌ๋ก ํด๊ฒฐํ ์ ์๋ ๋ฌธ์ ์
์ฑ์ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด์ ์๊ธฐ๋ ๋ฌธ์ ์ ๋ค์ ์๋ 2๊ฐ์ง๋ก ๋๋ ์ ์๋ค.
- ์ฌ๋ฌ ๋ทฐ๊ฐ ๊ฐ์ ์ํ์ ์์กดํ๋ ๊ฒฝ์ฐ => ์ง๋์น๊ฒ ์ค์ฒฉ๋ ์ปดํฌ๋ํธ๋ฅผ ํต๊ณผํ๋ prop๋ ์ฅํฉํ ์ ์์ผ๋ฉฐ ํ์ ์ปดํฌ๋ํธ์์๋ ์๋ํ์ง ์๋๋ค.
- ์๋ก ๋ค๋ฅธ ๋ทฐ์ ์์ ์ด ๋์ผํ ์ํ๋ฅผ ๋ฐ์ํด์ผ ํ๋ ๊ฒฝ์ฐ => ์ง์ ๋ถ๋ชจ/์์ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๊ฑฐ๋ ์ด๋ฒคํธ๋ฅผ ํตํด ์ํ์ ์ฌ๋ฌ ๋ณต์ฌ๋ณธ์ ๋ณ๊ฒฝ ๋ฐ ๋๊ธฐํ ํ๋ ค๋ ๋ฑ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ผ ํ๋ค. ์ด๋ฌํ ํจํด์ ๋ชจ๋ ๋ถ์์ง๊ธฐ ์ฝ๊ณ ์ ์ง๋ณด์๊ฐ ๋ถ๊ฐ๋ฅํ๋ค.
2. Vuex
- Vue.js ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํ ์ํ ๊ด๋ฆฌ ํจํด + ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ๋ค๋ฅธ ์ํ ๊ด๋ฆฌ ํจํด์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋น๊ตํ์ ๋ ๋ทฐ์ ๋ฐ์์ฑ(Reactivity) ์ฒด๊ณ๋ฅผ ํจ์จ์ ์ผ๋ก ํ์ฉํ์ฌ ํ๋ฉด์ ์ ๋ฐ์ดํธ ํ๋ค๋ ์ฐจ์ด์ ์ด ์๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ชจ๋ ์ปดํฌ๋ํธ์ ๋ํ ์ค์ ์ง์ค์ ์ ์ฅ์ ์ญํ ์ ํ๋ฉฐ ์์ธก ๊ฐ๋ฅํ ๋ฐฉ์์ผ๋ก ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค.
โป ์ค๋ํ ๊ท๋ชจ์ SPA๋ฅผ ๊ตฌ์ถํ๋ ๊ฒฝ์ฐ๊ฐ ์๋๊ณ , ์ฑ์ด ๋จ์ํ๋ค๋ฉด Vuex์์ด ๊ฐ๋จํ ๊ธ๋ก๋ฒ ์ด๋ฒคํธ ๋ฒ์ค (opens new window)๋ง์ผ๋ก๋ ์ํ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค!
2-1) Vuex ์ค์น ๋ฐ ๋ฑ๋ก
์๋ ๋ช ๋ น์ด๋ก ํ๋ก์ ํธ์ vuex๋ฅผ ์ค์นํ๋ค.
$ npm install vuex
๊ทธ๋ฆฌ๊ณ storeํด๋์์ index.jsํ์ผ์ ์์ฑํด vuex๋ฅผ ๋ฑ๋กํ๋ค.
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
// ...
});
๋ง์ง๋ง์ผ๋ก ํ๋ก์ ํธ์ main.jsํ์ผ์ store>index.js ํ์ผ์ ๋ถ๋ฌ์ ๋ฑ๋กํ๋ค.
import store from './store' //store.js๋ฅผ ๋ถ๋ฌ์ค๋ ์ฝ๋
new Vue({
el: '#app',
store, //์ถ๊ฐ!!
components: { App },
template: '<App/>'
})
3. state
3-1) state ๋ฑ๋ก
// store.js (Vuex)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
// state ์ถ๊ฐ
state: {
counter: 0
}
});
3-2) state ์ ๊ทผ
// App.vue
computed: {
doubleCounter() {
return this.$store.state.counter * 2;
}
},
// Child.vue
computed: {
doubleCounter() {
return this.$store.state.counter * 2;
}
},
4. Getters & Mutations
์ ์ฝ๋๋ ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ๊ฐ์ ๋ก์ง์ ๋นํจ์จ์ ์ผ๋ก ์ค๋ณต ์ฌ์ฉํ๊ณ ์๋ค. ์ด๋ฅผ Vuex์ state๋ณ๊ฒฝ์ ๊ฐ ์ปดํฌ๋ํธ์์ ์ํํ์ง ์๊ณ , vuex์์ getters ๋๋ mutations๋ฅผ ์ด์ฉํ์ฌ ์ํํ๋๋ก ํ๊ณ ๊ฐ ์ปดํฌ๋ํธ์์ ์ํ ๋ก์ง์ ํธ์ถํ๋ฉด ํจ์จ์ ์ด๋ค.
๊ณตํต์ | getters, mutations, (+actions) ๋ชจ๋ state ๊ฐ์ ๋ณ๊ฒฝํ๋ ๋ก์ง๋ค์ |
์ฐจ์ด์ | - mutations๋ ์ธ์๋ฅผ ๋ฐ์ vuex์ ๋๊ฒจ์ค ์ ์๋ค. - getters๋ comuted์ ๋ฑ๋กํ๊ณ , mutations๋methodes์ ๋ฑ๋กํ๋ค. |
4-1) getters ๋ฑ๋ก๊ณผ ์ฌ์ฉ
// store.js (Vuex)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
counter: 0
}
// getters ์ถ๊ฐ
getters: {
getCounter: function (state) {
return state.counter;
},
doubleCounter: function (state) {
return state.counter * 2;
}
},
});
// App.vue
computed: {
parentCounter() {
this.$store.getters.getCounter;
}
},
// Child.vue
computed: {
childCounter() {
this.$store.getters.getCounter;
}
},
4-2) mutations ๋ฑ๋ก๊ณผ ์ฌ์ฉ
// store.js (Vuex)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
counter: 0
}
// mutations ์ถ๊ฐ
mutations: {
addCounter: function (state, payload) {
return state.counter++;
}
}
});
// App.vue
methods: {
addCounter() {
// this.$store.state.counter++;
this.$store.commit('addCounter');
}
},
๊ฐ ์ปดํฌ๋ํธ์์ Vuex ์ state ๋ฅผ ์กฐ์ํ๋๋ฐ ํ์ํ ํน์ ๊ฐ๋ค์ ๋๊ธฐ๊ณ ์ถ์ ๋๋ commit() ์ ๋ ๋ฒ์งธ ์ธ์๋ฅผ ์ถ๊ฐํด ๊ฐ์ ๋๊ธธ ์ ์๋ค.
this.$store.commit('addCounter', 10);
this.$store.commit('addCounter', {
value: 10,
arr: ["a", "b", "c"]
});
mutations: {
// payload ๊ฐ { value : 10 } ์ผ ๊ฒฝ์ฐ
addCounter: function (state, payload) {
state.counter = payload.value;
}
}
5. Actions
- Mutations ์๋ ์์ฐจ์ ์ธ ๋ก์ง๋ค๋ง ์ ์ธํ๊ณ Actions ์๋ ๋น ์์ฐจ์ ๋๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ก์ง๋ค์ ์ ์ธํ๋ค.
- setTimeout() ์ด๋ ์๋ฒ์์ http ํต์ ์ฒ๋ฆฌ ๊ฐ์ด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์ฌ ํ์ด๋ฐ์ด ์์ธก๋์ง ์์ ๋ก์ง์ Actions ์ ์ ์ธํ๋ค.
5-1) actions ๋ฑ๋ก
// store.js
export const store = new Vuex.Store({
actions: {
getServerData: function (context) {
return axios.get("sample.json").then(function() {
// ...
});
},
delayFewMinutes: function (context) {
return setTimeout(function () {
commit('addCounter');
}, 1000);
}
}
});
5-2) actions ์ฌ์ฉ
actions ๋ฅผ ํธ์ถํ ๋๋ ์๋์ ๊ฐ์ด dispatch() ๋ฅผ ์ด์ฉํ๋ค.
// App.vue
methods: {
addCounter() {
this.$store.dispatch('addCounter');
}
},
5-3) actions์ ์ธ์ ๊ฐ ๋๊ธฐ๊ธฐ
<!-- by ์ duration ๋ฑ์ ์ฌ๋ฌ ์ธ์ ๊ฐ์ ๋๊ธธ ๊ฒฝ์ฐ, ๊ฐ์ฒด์์ key - value ํํ๋ก ์ฌ๋ฌ ๊ฐ์ ๋๊ธธ ์ ์๋ค -->
<button @click="asyncIncrement({ by: 50, duration: 500 })">Increment</button>
export const store = new Vuex.Store({
actions: {
// payload ๋ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉํ๋ ์ธ์ ๋ช
asyncIncrement: function (context, payload) {
return setTimeout(function () {
context.commit('increment', payload.by);
}, payload.duration);
}
}
})
6. Map ํฌํผ
์์ธํ๊ฒ ์ค๋ช ๋ ์ฌ์ดํธ
Vuex ์ ๋ด์ฅ๋ helper ํจ์๋ก ์ด๋ฏธ ์์์ ํ๋ฒ ๊ฐ๋ ์ฑ์ด ์ฌ๋ผ๊ฐ ์ฝ๋๋ฅผ ๋ ์ง๊ด์ ์ด๊ฒ ์์ฑํ ์ ์๋ค.
- mapState
- mapGetters
- mapMutations
- mapActions
// ์ฌ์ฉ ๋ฐฉ๋ฒ 1
...mapState(['books', 'cart'])
// ์ฌ์ฉ ๋ฐฉ๋ฒ 2
...mapMutations({
changeBooks: 'setBooks'
})
// ์ฌ์ฉ ๋ฐฉ๋ฒ 3
...mapGetters({
CartItemsCount: state => state.cart.length
})
ex)
// App.vue
import { mapState, mapMutations, mapGetters, mapActions } from 'vuex';
export default {
computed: {
...mapState(['books']),
...mapGetters(['checkOutOfStock']),
},
methods: {
...mapActions(['fetchBooks', 'addBookToCart']),
...mapMutations({changeBooks: 'setBooks'})
},
}
'๐ปWEB FrontEnd > ํ๋ ์์ํฌ Vue' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
CSR์ SSR์ ์ฅ๋จ์ (0) | 2021.02.08 |
---|---|
vue์ ๋ฐ์์ฑ reactivity (0) | 2021.02.07 |
Single File Components ์ฒด๊ณ (0) | 2021.02.06 |
Vue์ template์์ฑ (0) | 2020.07.04 |
๋ทฐ HTTP ํต์ (0) | 2020.07.02 |