* vuex store 모듈화가 된 후 기준 실습임 *
1. state
* state을 실행하기 위해서는 Commponent의 computed 영역 내에 작성을 해야한다.
state실습을 위한 store폴더 내에 index.js 와 testStore.js
//testStore.js
const testStore = {
namespaced: true,
state: { // 공통 관리되는 상태값을 관리, 접근방법- this.$store.state.items
count: 33,
},
getters: { // 공유되는 상태 값을 조회 로직을 관리, 접근방법 - this.$store.getters['경로명/함수명']
},
mutations: { // 상태 값을 변경하는 로직을 관리, 접근방법 - this.$store.commit('경로명/함수명')
},
actions: { // 비동기 통신 및 동작을 정의하고 관리, 접근방법 - this.$store.dispatch('경로명/함수명')
},
};
export default testStore;
//index.js
import Vue from 'vue';
import Vuex from 'vuex';
import testStore from '@/store/testStore';
import joinStore from '@/store/joinStore';
import loginStore from '@/store/loginStore';
Vue.use(Vuex);
export default new Vuex.Store({
strict: true,
modules: {
testStore,
joinStore,
loginStore,
},
});
1) Vue 구성 요소에 Vuex 상태 가져오기
//CounterA.vue
<template>
<div> {{ count }} </div>
</template>
<style scoped>
</style>
<script>
export default {
computed: {
count() {
return this.$store.state.testStore.count
}
}
}
</script>
#화면 출력 결과
2) mapState
- state의 helper함수이다.
* helper함수 ? vuex를 좀더 깔끔하고 간결하게 사용할 수 있게 도와주는 함수, 코드가 길어지는걸 대비할 수 있다.
<template>
<div> {{ count }} </div>
</template>
<style scoped>
</style>
<script>
import { mapState } from 'vuex'
export default {
computed:
mapState({
count: state => state.testStore.count,
})
}
</script>
하지만 더 간결하게 하는 방법이있다
mapState{ } 를 ...mapState{[ ]} 로 바꿔주면 된다.
<template>
<div> {{ count }} </div>
</template>
<style scoped>
</style>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState('testStore',[
'count'
])
}
}
</script>
#화면 출력 결과 ( * 1)과 동일한 결과 )
2. getter
* getters을 실행하기 위해서는 Commponent의 computed 영역 내에 작성을 해야한다.
getter 실습을 위한 store폴더 내에 index.js
const testStore = {
namespaced: true,
state: {
todos: [
{id : 1, text: "안녕하세요", done: true},
{id : 2, text: "안녕히계세요", done: false},
]
},
getters: {
doneTodos(state){
return state.todos.filter(todo => todo.done)
}
},
mutations: {
},
actions: {
},
};
export default testStore;
1) getters 접근 기본 ①
<template>
<div> {{ doneTodosCount }} </div>
</template>
<style scoped>
</style>
<script>
import { mapState } from 'vuex'
export default {
computed: {
doneTodosCount (){
return this.$store.getters['testStore/doneTodos']
}
}
}
</script>
# 화면 출력 결과
- 이런식으로 getters는 메서드를 통해 호출했을 경우 가장 '첫번째 요소' 의 값만 반환한다
2) getters 접근 기본 ②
<template>
<div> {{ doneTodosCount }} </div>
</template>
<style scoped>
</style>
<script>
import { mapState } from 'vuex'
export default {
computed: {
doneTodosCount(){
return this.$store.state.testStore.todos.filter(todo => todo.done).length
}
}
}
</script>
# 화면 출력 결과
todo.done이 true인 length를 반환한다
{id : 1, text: "안녕하세요", done: true},
{id : 2, text: "안녕히계세요", done: true},
만약 위와 같다면 결과는 2 가 나오게 된다.
3) 속성 스타일 액세스
- getter는 store.getters 객체에 노출되며 속성으로 값에 액세스 한다.
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
- getters는 두 번째 인수로 다른 getter도 받을 수 있다.
getters: {
// ......
doneTodoCount(state, getters){
return getters.doneTodos.length
}
},
위와같이 두번째인자에 getters를 넣어 다른 getters를 받는 예제이다.
<template>
<div> {{ doneTodosCount }} </div>
</template>
<style scoped>
</style>
<script>
import { mapState } from 'vuex'
export default {
computed: {
doneTodosCount(){
return this.$store.getters['testStore/doneTodoCount']
}
}
}
</script>
# 화면 출력 결과
4) 메서드 스타일 액세스
- 함수를 반환하여 getter에 인수를 전달할 수 도 있다.
getters: {
// ......
getTodoById : (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
},
<template>
<div> {{ doneTodosCount }} </div>
</template>
<style scoped>
</style>
<script>
import { mapState } from 'vuex'
export default {
computed: {
doneTodosCount(){
return this.$store.getters['testStore/getTodoById',1]
}
}
}
</script>
얘는 실패..
doneTodosCount(){
return this.$store.getters['testStore/getTodoById',1]
}
에서 인수전달 하는데 있어서 문제가 생긴것 같다...
** 추후 성공해서 수정하기!!!!!!!!! ^^
5) mapGetters
{
...mapGetters('testStore',[
'doneTodos'
]),
doneTodosCount(){
return this.doneTodos
}
}
# 화면 출력 결과
3. mutation
1) mutation 접근 기본
store폴더 내에 index.js
state: {
tardy: 0,
},
mutations: {
addTardy(state) {
state.tardy++;
},
},
<template>
<div>
mutation test :
<b-button @click="addTardy">
버튼
</b-button>
</div>
</template>
<style scoped>
</style>
<script>
export default {
methods:
{
addTardy(){
this.$store.commit('testStore/addTardy');
console.log(this.$store.state.testStore.tardy)
}
}
}
</script>
버튼을 클릭하면 state에 있는 tardy가 1씩 증가하면 그걸 콘솔창에 나오게끔 만들었다.
# 화면 출력 결과
2) 인자값 전달 ①
store폴더 내에 index.js
state: {
tardy: 0,
},
mutations: {
addTardy2(state, n){
state.tardy += n
}
},
<template>
<div>
mutation test :
<b-button @click="addTardy">
버튼
</b-button>
</div>
</template>
<style scoped>
</style>
<script>
export default {
methods:
{
addTardy(){
this.$store.commit('testStore/addTardy2',10);
console.log(this.$store.state.testStore.tardy)
}
}
}
</script>
commit('경로명/함수명',인자값) 을 넣어 인자를 전달할수있다
그래서 인자값 10을 보내면
addTardy2(state, n){
state.tardy += n
}
에 의해 state의 tardy값이 초기값0에서 10씩 증가하는 모습을 볼수있다.
# 화면 출력 결과
3) 인자값 전달(feat. payload) ②
store폴더 내에 index.js
state: {
tardy: 0,
},
mutations: {
addTardy3(state, payload){
state.tardy += payload.amount
}
},
<template>
<div>
mutation test :
<b-button @click="addTardy">
버튼
</b-button>
</div>
</template>
<style scoped>
</style>
<script>
export default {
methods:
{
addTardy(){
this.$store.commit('testStore/addTardy3', {
amount: 10
});
console.log(this.$store.state.testStore.tardy)
}
}
}
</script>
위와 같이 인자값에 저런식으로 넣어주면 payload를 이용하여 접근할 수 있다
# 화면 출력 결과
위에 방법을 조금 변형해본다면?
methods:
{
addTardy(){
this.$store.commit({
type: 'testStore/addTardy3',
amount: 10
});
console.log(this.$store.state.testStore.tardy)
}
}
commit('경로명/함수명',인자값)
대신
commit({ type: '경로명/함수명' , 키: 값 }) 으로 바꿔주었다
결과는 같다.
4. actions
1) 기본 ①
store폴더 내에 index.js
state: {
tardy: 0,
},
mutations: {
addTardy3(state, payload){
state.tardy += payload.amount
}
},
actions: {
addTardy(result) {
result.commit('addTardy');
},
},
<template>
<div>
mutation test :
<b-button @click="addTardy">
버튼
</b-button>
</div>
</template>
<style scoped>
</style>
<script>
export default {
methods:
{
addTardy(){
this.$store.dispatch('testStore/addTardy');
console.log(this.$store.state.testStore.tardy)
}
}
}
</script>
# 화면 출력 결과
위 코드를 를 더 간결하게 할 수도 있다 ▼
2) 기본 ②
store폴더 내에 index.js
state: {
tardy: 0,
},
mutations: {
addTardy3(state, payload){
state.tardy += payload.amount
}
},
actions: {
addTardy2 ( {commit }){
setTimeout(() => {
commit('addTardy')
}, 1000)
}
},
<template>
<div>
mutation test :
<b-button @click="addTardy">
버튼
</b-button>
</div>
</template>
<style scoped>
</style>
<script>
export default {
methods:
{
addTardy(){
this.$store.dispatch('testStore/addTardy2')
console.log(this.$store.state.testStore.tardy)
}
}
}
</script>
요렇게 지정된 시간이 지나면 함수를 실행하는 setTimeOut을 이용해서 코드를 짤 수 도 있다
1000 > 10초인데 10초마다 state의 tardy가 1씩 증가한다.
3) mapActions
- 추후 추가하기
4) promise
프로미스의 resolve, reject는 비동기 작업의 처리과정에서 성공/실패를 구분하는 방법이다.
- promise 객체와 resolve를 할당받은 메소드만이 async와 await 키워드를 사용할 수 있다.
- promise 객체를 부여받은 메소드는 내부에는 resolve() 메소드를 부여한다.
- await 키워드를 할당받은 메소드는 promise 내부에서 resolve()가 실행될 때까지 우선적으로 실행된다.
- resolve()가 실행되기 전까지 다른 메소드는 실행될 수 없다.
출처: https://devraphy.tistory.com/229 [개발자를 향하여:티스토리]
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}
store.dispatch('actionA').then(() => {
// ...
})
쉽게 말하면 비동기 처리를 순서대로 실행시키기 위한 기능이다
만약 promise가 없으면 함수에서 콜백>콜백>콜백 이런식으로 되어서 가독성도 좋지 않고 힘들다고 한다.
resolve 함수는 성공시, reject는 실패할때 사용된다.
위에 resolve나 reject가 둘중 한개라도 있어야 다음 then으로 넘어간다.
'나의 개발 기록 > Vue' 카테고리의 다른 글
[Vue.js] vue에서 새창으로 form을 post방식으로 전송하기 (0) | 2022.09.03 |
---|---|
[Vue.js] state값 새로고침되도 값 유지되도록 하기(vuex-persistedstate ) (0) | 2022.09.02 |
[Vue.js] vue store 모듈화 (feat.vuex) (0) | 2022.08.17 |
[Vue.js] vscode 디버깅 하기 (feat. Debugger for Chrome) (2) | 2022.08.15 |
[vue.js] vue-router의 네비게이션 가드 (0) | 2022.07.29 |
댓글