CoachForm 컴포넌트 내부에서 formData를 CoachRegistration 컴포넌트에 노출시키기만 하면 된다.
이론적으로는 CoachForm 내부에서 Vuex저장소에 직접 접근할 수도 있다.
어느 컴포넌트에서든 Vuex저장소와 통신이 가능하므로.
그러나 이 CoachForm 컴포넌트를 재사용가능하고 개별적으로 작동하며 부모컴포넌트와 함께 작동하도록 해보자.
(개인적인 취향일 뿐이다.)
입력된 데이터를 부모컴포넌트(CoachRegistration.vue)에게 알리도록 해보자.
그러면 부모 컴포넌트인 CoachRegistration컴포넌트가 Vuex와 통신하게 된다.
이건 여러 방법 중 하나일 뿐이다.
// CoachForm.vue
submitForm() {
this.validForm();
if (!this.formIsValid) {
return;
}
const formData = {
first: this.firstName.val,
last: this.lastName.val,
desc: this.description.val,
rate: this.rate.val,
areas: this.areas.val,
};
this.$emit('save-data', formData);
},
모두 입력하고 나면 CoachRegistration 내부에서 이 수신 데이터를 받을 수 있다.
우리가 emit한 커스텀 이벤트인 save-data를 listen할 수 있고, saveData라는 메서드를 호출한다.
saveData메서드의 매개변수가 되며, 저장소와 통신하려면 이 데이터가 필요하다.
<!--CoachRegistration.vue-->
<template>
<section>
<base-card>
<h2>Register as a coach now!</h2>
<coach-form @save-data="saveData"></coach-form>
</base-card>
</section>
</template>
<script>
import CoachForm from '../../components/coaches/CoachForm.vue';
import BaseCard from '../../components/ui/BaseCard.vue';
export default {
components: { CoachForm, BaseCard },
methods: {
saveData(data) {
this.$store.dispatch('coaches/registerCoach', data);
},
},
};
</script>
actions.js의 coachData 객체에서 id는 new Data().toISOString을 써서 id를 생성하거나,
'c3'로 하드코딩할 수도 있다. (물론 두 번 등록할 경우 id가 중복되어서는 안된다.)
지금은 하드코딩하고, 나중에 이를 서버로 보내면 서버가 더 좋은 id를 준다.
//actions.js
export default {
registerCoach(context, data) {
const coachData = {
id: 'c3',
firstName: data.first,
lastName: data.last,
areas: data.areas,
description: data.desc,
hourlyRate: data.rate,
};
context.commit('registerCoach', coachData);
},
};
// mutations.js
export default {
registerCoach(state, payload) {
const coachData = payload;
state.coaches.push(coachData); //이건 사실 좋은 방법이 아니다. 하지만 actions에서 변형했으므로 ok.
},
};
이제 이 액션을 dispatch할 수 있다.
//CoachRegistration.vue
methods: {
saveData(data) {
this.$store.dispatch('coaches/registerCoach', data); //data를 두번째 인수로 제공.
},
},
이제 잘 작동한다.
이 양식을 제출하면 자동으로 다른 페이지로 이동하면 좋을 것 같다.
All Coaches 페이지로.
this.$router.push()를 이용해 /coaches로 push하면 된다.
// CoachRegistration.vue
methods: {
saveData(data) {
this.$store.dispatch('coaches/registerCoach', data);
this.$router.push('/coaches');
//OR
this.$router.replace('/coaches');
},
},
또는 replace메서드를 router메서드에 호출.
push와 마찬가지로 이 역시 사용자를 이동시켜주지만, 이동 후에는 이전 페이지로 돌아갈 수 없다는 차이점이 있다.
양식 제출 후에는 양식 페이지로 돌아가면 안되기에 유용하다.
따라서 여기선 push 대신 replace를 사용하자.
참고로 새로고침 할 때마다 생성한 코치가 사라진다.
왜냐하면 현재는 메모리에 임시로 저장되기 때문.
→ 그래서 나중에 서버에 HTTP를 추가하는 이유.
이제 등록이 완료되면 'Register as Coach'버튼이 표시되지 않도록 하려고 한다.
그러려면 해당 사용자가 언제 가입했는지 확인할 수 있어야한다.
그리고 Vuex를 사용해서 해당 사용자가 코치인지 확인할 수 있게 한다
index.js에서 루트 state를 추가해 이 앱을 사용중인 사용자의 id를 관리해보자.
아까 하드코딩으로 'c3'를 id로 설정했다. 나중에 인증관련 강의를 학습한 뒤에는 여기에 실제 사용자 id를 넣을거다.
해당 id를 가진 코치가 이미 있는지 확인해보자.
actions.js에서 registerCoach에서 더이상 id를 하드코딩하지 않겠다. 대신 루트 id를 사용하겠다.
id를 주는 루트 getter만 있으면 된다.
// index.js
state() {
return {
userId: 'c3',
};
},
getters: {
userId(state) {
return state.userId; //'c3'
},
},
// coaches > actions.js
export default {
registerCoach(context, data) {
const coachData = {
id: context.rootGetters.userId,
firstName: data.first,
lastName: data.last,
areas: data.areas,
description: data.desc,
hourlyRate: data.rate,
};
context.commit('registerCoach', coachData);
},
};
getters에서 사용자가 이미 코치라면 true를 반환하고, 그 외에는 false를 반환하는 isCoach 추가.
// coaches > getters
coaches(state) {
return state.coaches;
},
hasCoaches(state) {
return state.coaches && state.coaches.length > 0;
},
isCoach(state, getters, rootState, rootGetters) {
const coaches = getters.coaches; //등록된 coach들
const userId = rootGetters.userId; //현재 유저id
return coaches.some(coach => coach.id === userId); //등록된 coach들에 현재유저 있는지
}
이렇게 하면 우리 사용자 id를 id로 갖는 코치가 하나라도 있다면 여기서 true를 반환하게 된다.
즉, true값은 이미 코치임을 의미한다.
안쓰는 매개변수 2개는 _, _2로 바꾸자.
isCoach(_, getters, _2, rootGetters) {
const coaches = getters.coaches;
const userId = rootGetters.userId;
return coaches.some(coach => coach.id === userId);
}
관행적 표현으로 이 인수들을 취하긴 하지만, 사용하지는 않는다는 뜻으로 이 프로젝트의 Linter를 의미한다.
이렇게 하면 현재 사용자id와 같은 id의 코치가 있으면 true를 얻게 된다.
이 방법의 단점은 코치인지 확인하기 위해 항상 모든 코치를 확인한다는 것.
이를 해결할 대안으로는 여기 coaches의 state에 userIsCoach라는 새로운 상태를 추가해서 사용자가 가입하는 즉시 true로 설정하는 방법도 있다.
// index.js
export default {
namespaced: true,
state() {
return {
userIsCoach: false,
coaches: [
{
id: 'c1',
firstName: 'Maximilian',
lastName: 'Schwarzmüller',
areas: ['frontend', 'backend', 'career'],
description:
"I'm Maximilian and I've worked as a freelance web developer for years. Let me help you become a developer as well!",
hourlyRate: 30,
},
{
id: 'c2',
firstName: 'Julie',
lastName: 'Jones',
areas: ['frontend', 'career'],
description:
'I am Julie and as a senior developer in a big tech company, I can help you get your first job or progress in your current role.',
hourlyRate: 30,
},
],
};
},
// 생략
};
CoachList에서 computed프로퍼티 추가할 수 있다.
//CoachList.vue
<template>
<base-button link to="/register" v-if="!isCoach">Register as Coach</base-button>
</template>
<script>
computed: {
isCoach() {
return this.$store.getters['coaches/isCoach'];
},
},
</script>
이제 코치로 등록하면 더이상 "Register as Coach"버튼이 뜨지 않는다.
이제 코치를 추가하거나 코치로 등록할 수있게 되었다.
빠진 것이 하나 있다.
빈 양식을 제출하면 안되므로, 이 양식에 유효성 검사를 추가해서 빈 양식 제출을 막아보자.
** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.
'Vue.js' 카테고리의 다른 글
[Udemy Vue 완벽가이드 Section16] 248. 연락처 양식 작업하기 (0) | 2023.12.13 |
---|---|
[Udemy Vue 완벽가이드 Section16] 247. 양식 유효성 검사 추가하기 (0) | 2023.12.13 |
[Udemy Vue 완벽가이드 Section16] 245. 코치 등록하기:양식 (0) | 2023.12.12 |
[Udemy Vue 완벽가이드 Section16] 244. 코치 필터링하기 (0) | 2023.12.12 |
[Udemy Vue 완벽가이드 Section16] 243. 코치 세부사항 컴포넌트 구축하기 (0) | 2023.12.12 |