Vue로 나만의 캘린더 만들어보기 - 3
2020-09-11 14:54:06

내가 등록한 일정 리스트 만들기

Main.vue

1
2
3
├── Calendar.vue
│ ├── Modal.Vue
├── TodoList.vue

TodoList 컴포넌트를 생성 하였고 이 컴포넌트에서 서버에 저장된 일정을 가지고 오려고

하였으나 검색할 조건의 데이터(년,월)를 가지고 있지 않아서 검색을 할 수가 없었다.

그래서 년,월의 데이터를 Calendar -> Main -> TodoList의 방식으로 진행을 하였는데

Main에서는 mounted 단계에서 $emit한 데이터에 접근이 가능 했지만 TodoList에서는

props에 데이터가 들어오는 걸 뷰 개발자 도구를 통해 확인 했지만 mounted 이전에 데이터 접근

이 안 되는 걸 알았고 Main에서 서버에 데이터를 요청한 다음 TodoList에 줘야 된다고 느꼈다.

예상한대로 Main에서 $emit을 받아오는 부분에 axios로 서버 데이터를 받아 오니 뷰 반응성도

적용 되고 원하는 그림으로 데이터가 출력이 되었다.

글 등록 시 TodoList에 출력

Modal창에서 글을 등록 시 서버에 전송을 하면서 화면에 바로 그리려면 Main 컴포넌트에

데이터를 전송 해야 하는데 Modal은 최하위 컴포넌트여서 거쳐 가기엔 불편 하므로 이러한 방법을

해결 하기 위해서 별개의 컴포넌트 to 컴포넌트로 통신이 가능한 이벤트 버스를 이용 해봤다.

middleware/eventbus.js

1
2
3
4
5
import Vue from "vue";

const eventBus = new Vue();

export default eventBus;

modal.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
import eventBus from "../../middleware/eventbus";

export default {
// ...
methods: {
save() {
// ... 서버에 전송 후
const data = {
year: this.year,
month: this.month,
day: this.clickDay,
message: this.message,
};
eventBus.$emit("addList", data);
},
},
};
</script>

Main.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
// ...
import eventBus from "../../middleware/eventbus";

export default {
// ...
created() {
eventBus.$on("addList", (payload) => {
if (this.list.length === 0) {
this.list.push([payload]);
} else if (this.list[this.list.length - 1].length > 4) {
this.list.push([payload]);
} else {
this.list[this.list.length - 1].push(payload);
}
});
},
};
</script>

이벤트버스를 통해 Modal에서 Main에 데이터를 전송하여 일정 리스트가 바뀌므로 반응성으로 인해

하위 컴포넌트 TodoList에 잘 노출이 되었다.

일정 삭제

마지막으로 지난 일정을 삭제할 수 있는 기능을 추가하려고 한다.

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
45
46
47
48
49
50
51
52
<div class="columns" v-for="(items, idx) in list" :key="idx">
<div class="column" v-for="(item, subIdx) in items" :key="subIdx">
<div class="card">
<header class="card-header">
<p class="card-header-title">
{{ item.year }}년 {{ item.month }}월 {{ item.day }}일
</p>
</header>
<div class="card-content">
<div class="content">{{ item.message }}</div>
</div>
<footer class="card-footer">
<button
class="card-footer-item button is-primary is-light"
@click="removeItem(idx, subIdx)"
>
삭제
</button>
</footer>
</div>
</div>
</div>

<script>
import axios from "axios";
import eventBus from "../../middleware/eventbus";

export default {
name: "TodoList",
props: ["year", "month", "list"],
data() {
return {
title: "내가 등록한 일정 리스트",
datas: null,
};
},
methods: {
removeItem(idx, subIdx) {
axios
.delete("http://localhost:3000/remove", {
data: {
// eslint-disable-next-line no-underscore-dangle
id: this.list[idx][subIdx]._id,
},
})
.then(() => {
eventBus.$emit("removeList", { idx, subIdx });
});
},
},
};
</script>

먼저 서버에 삭제를 요청한 다음 완료가 되면 이벤트 버스로 리스트를 보관하고 있는 Main에

통신을 하여 해당 위치의 값을 배열에서 삭제를 해주었더니 화면에 적용이 잘 되었다.

이로서 Vue 찍먹? 해 본 느낌인데 아직은 jQuery나 EJS에 비해 익숙하지 않다 보니.. 😓

다음 프로젝트에서 Vue-Router & Vuex를 공부해서 연습 해봐야겠다!

참고

Prev
2020-09-11 14:54:06
Next