일정 등록
일정 등록은 달력의 날짜를 클릭 시 modal창이 나와서 입력을 하게끔 만들고 싶어졌다.
css 프레임워크에 modal example이 나와 있는데 class의 값만 주면 되는 상황 이였다.
Model.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <template> <div class="modal"> <div class="modal-background"></div> <div class="modal-card"> <header class="modal-card-head"> <p class="modal-card-title">날짜</p> <button class="delete" aria-label="close"></button> </header> <section class="modal-card-body"> <textarea class="textarea" :placeholder="placeholder"></textarea> </section> <footer class="modal-card-foot"> <button class="button is-success">{{ buttonMessage[0] }}</button> <button class="button">{{ buttonMessage[1] }}</button> </footer> </div> </div> </template>
<script> export default { data() { return { placeholder: "오늘 할 일을 적어주세요", buttonMessage: ["저장", "취소"], }; }, }; </script>
|
어제 작성 했었던 Calendar.vue에 Modal.vue를 import 시켜서 Modal.vue는 하위 컴포넌트가 되었으므로
상위 컴포넌트(Calendar.vue)에서 modal의 오픈 상태를 가지고 있어야 했으며, modal을 열기 위해
하위 컴포넌트(Modal.vue)에 데이터를 보낼려면 props를 이용 해야 했고, 그 반대로 하위 컴포넌트에서
modal 창을 닫으면 상위 컴포넌트에 modal이 닫혔다로 상태를 변경을 해주기 위해서 $emit을 사용 했다.
Calendar.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <template> ... <td v-for="(day, secondIdx) in date" :key="secondIdx" :class="{ 'has-text-grey': idx === 0 && day >= lastMonthStart, 'has-text-danger': dates.length - 1 === idx && nextMonthStart > day, 'has-text-primary': day === today && month === currentMonth && year === currentYear, }" @click="showModal" > {{ day }} </td> ... <Modal v-bind:modalOpen="modalOpen" v-on:closeModal="closeModal"></Modal> </template> <script> import Modal from './Modal';
export default { ... components: { Modal, }, data() { ... modalOpen: false, }, methods: { ... showModal() { this.modalOpen = true; }, closeModal(event) { this.modalOpen = event; }, }, } </script>
|
Modal.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <template> <div class="modal" :class="{'is-active': modalOpen}"> <div class="modal-background" @click="closeModal"></div> ... </div> </template> <script> export default { name: "Modal", props: ["modalOpen"], data() { return { placeholder: "오늘 할 일을 적어주세요", buttonMessage: ["저장", "취소"], }; }, methods: { closeModal() { this.$emit("closeModal", false); }, }, }; </script>
|
글 등록
v-model 지시자를 써서 글을 작성 해봤으나 한글은 끝 단어 바인딩이 정상적으로 되질 않아서
검색을 해 봤더니 Vue 공식문서에도 나와 있는 사양이라고 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> ... <section class="modal-card-body"> <textarea class="textarea" :placeholder="placeholder" @input="typing" :value="message" ></textarea> </section> ... </template>
<script> export default { ... methods: { typing(event) { this.message = event.target.value; }, ... }, } </script>
|
작성한 글을 서버에 보내서 DB에 저장을 하려고 하면 통신을 보내야 하는데
Vue에서는 axios를 쓴다고 하길래 나는 기존에도 자주 사용하던 HTTP 클라이언트라 좋았다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <template> ... <footer class="modal-card-foot"> <button class="button is-primary" @click="save"> {{ buttonMessage[0] }} </button> <button class="button" @click="closeModal">{{ buttonMessage[1] }}</button> </footer> </template>
<script> import axios from 'axios';
export default { ... methods: { ... save() { axios.post('http://localhost:3000/save', { message: this.message, date: `${this.year}-${this.month}-${this.clickDay}`, }).then((result) => { console.log('result', result.data); }).catch((e) => { console.log('e', e); }); }, }, } </script>
|
다음에는 저장된 일정을 볼 수 있는 리스트를 만들어야겠다.
참고