Map 헬퍼
컴포넌트에 연결된 스토어의 스테이트, 게터, 액션, 뮤테이션이 많아질 경우 코드가 복잡해지게 됩니다. 이러한 복잡한 코드를 간결하게 작성 가능하도록 Vuex는 Map 헬퍼를 제공합니다.
- mapState
- mapGetters
- mapActions
- mapMutations
Map 헬퍼와 전개 연산자를 사용해 객체의 속성으로 간편한 설정이 가능합니다.
// 사용 방법 1
...mapState(['books', 'cart'])
// 사용 방법 2
...mapMutations({
changeBooks: 'setBooks'
})
// 사용 방법 3
...mapGetters({
CartItemsCount: state => state.cart.length
})
BookList
컴포넌트에 Map 헬퍼를 활용하는 예를 살펴보겠습니다.
vuex
모듈에서 Map 헬퍼를 불러옵니다.mapState
헬퍼를 사용해 스토어의books
를 가져와 계산된 속성으로 설정합니다.mapGetters
헬퍼를 사용해 스토어의checkOutOfStock
동적 게터를 가져와 계산된 속성으로 설정합니다.
// components/BookList.vue
import { mapState, mapGetters } from "vuex"; // [1]
export default {
name: 'BookList',
computed: {
...mapState(['books']), // [2]
// books() {
// return this.$store.state.books;
// },
...mapGetters(['checkOutOfStock']), // [3]
// checkOutOfStock() {
// return this.$store.getters.checkOutOfStock;
// }
}
}
컴포넌트에 바인딩 된 Map 헬퍼 내부에서 컴포넌트의 데이터에 접근해 처리할 수도 있습니다.
// components/BookList.vue
export default {
name: 'BookList',
data () {
return {
bookIndex: 2
}
},
computed: {
...mapState({
specificBook(state) {
return state.books[this.bookIndex]
}
})
}
}
주의!
Map 헬퍼 내부에서 this
를 사용할 경우, 화살표 함수를 사용하면 안됩니다. 화살표 함수 내부의 this
는 컴포넌트가 아닌 undefined
입니다.
computed: {
...mapState({
specificBook: state => state.books[this.bookIndex] // ✖︎ this === undefined
})
}
ShoppingCart
컴포넌트 또한 Map 헬퍼를 활용할 수 있습니다.
// components/ShoppingCart.vue
import { mapGetters } from "vuex";
export default {
name: 'ShoppingCart',
computed: {
...mapGetters({
books: 'cartBooks',
total: 'cartTotal'
}),
// books() {
// return this.$store.getters.cartBooks;
// },
// total() {
// return this.$store.getters.cartTotal;
// }
},
}
액션 또한 Map 헬퍼를 사용해 컴포넌트에 바인딩 할 수 있습니다.
- 스토어의
fetchBooks
,addBookToCart
액션을 컴포넌트의 메서드로 바인딩합니다. - 컴포넌트 생성 시점 훅 함수 내부에서 컴포넌트에 바인딩된 스토어의 액션을 활용할 수 있습니다.
// components/BookList.vue
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
name: 'BookList',
// ...
created() {
this.fetchBooks().then(() => (this.loading = false)) // [2]
// this.$store.dispatch("fetchBooks").then(() => (this.loading = false));
},
methods: {
...mapActions(['fetchBooks', 'addBookToCart']), // [1]
// addBookToCart(book) {
// this.$store.dispatch("addBookToCart", book);
// }
}
}
ShoppingCart
컴포넌트의 스토어 액션 바인딩 예
// components/ShoppingCart.vue
import { mapGetters, mapActions } from "vuex";
export default {
name: "ShoppingCart",
// ...
methods: {
...mapActions({
purchageBook: "purchage"
})
// purchage() {
// this.$store.dispatch("purchage");
// }
}
};
ShoppingCart
의 템플릿 코드에 사용된 $store.state.purchageStatus
또한 Map 헬퍼를 사용해 코드를 간소화 할 수 있습니다.
vuex
모듈에서mapState
를 불러옵니다.mapState
헬퍼를 사용해 스토어의purchageStatus
스테이트를 계산된 속성으로 설정합니다.- 템플릿 코드에 계산된 속성
purchageStatus
를 사용해 간소화 합니다.
<template>
<div class="shopping-cart">
<!-- ... -->
<p v-if="purchageStatus">{{ purchageStatus }}</p> <!-- 3 -->
<!-- <p v-if="$store.state.purchageStatus">{{ $store.state.purchageStatus }}</p> -->
</div>
</template>
<script>
import { mapGetters, mapActions, mapState } from "vuex"; // [1]
export default {
name: "ShoppingCart",
computed: {
...mapState(['purchageStatus']), // [2]
...mapGetters({
books: "cartBooks",
total: "cartTotal"
})
},
// ...
}
</script>