IT Study./VF
21. Vue와 Firebase로 나만의 사이트 만들기 - 하위메뉴 추가하기
impnem
2022. 5. 14. 20:56
VF - 21강
- 이번 강에서는 하위 메뉴를 추가할 것이다.
- 하지만 하위 메뉴에 추가하기가 들어가면 코드가 난잡해서 코딩하기가 쉽지 않아진다.
- 강의 자체도 작성된 코드를 설명하며 끝이났으며, 필자도 코드를 따라 적으면서 이해하였다.
- 아래의 코드를 따라쳐보며 작성하자.
<!-- menuView.vue -->
<template>
<div>
<v-list-item>
<v-list-item-content>
<v-list-item-title class="text-h6">
Menu
</v-list-item-title>
<v-list-item-subtitle>
0.0.1
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider></v-divider>
<v-list>
<!-- 메인 아이템 불러오기 -->
<v-list-group
v-for="(item, i) in items"
:key="i"
v-model="item.active"
:prepend-icon="item.icon"
no-action
>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title>
{{ item.title }}
<v-btn @click="openDialogItem(i)" icon><v-icon>mdi-pencil</v-icon></v-btn>
</v-list-item-title>
</v-list-item-content>
</template>
<!-- 서브 아이템 불러오기 -->
<v-list-item
v-for="(subItem, j) in item.subItems"
:key="j"
:to="subItem.to"
>
<v-list-item-content>
<v-list-item-title>
{{ subItem.title }}
<v-btn @click="openDialogSubItem(i, j)" icon><v-icon>mdi-pencil</v-icon></v-btn>
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<!-- 서브 아이템 추가하기 -->
<v-list-item @click="openDialogSubItem(i, -1)">
<v-list-item-icon>
<v-icon>mdi-plus</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>추가하기</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-group>
<!-- 메인 아이템 추가하기 -->
<v-list-item @click="openDialogItem(-1)">
<v-list-item-icon>
<v-icon>mdi-plus</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>추가하기</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
<!-- 메인 아이템 수정 dialog -->
<v-dialog v-model="dialogItem" max-width="400">
<v-card>
<v-card-title>
메인 아이템 수정
<v-spacer></v-spacer>
<v-btn @click="saveItem" icon color="success"><v-icon>mdi-content-save</v-icon></v-btn>
<v-btn @click="dialogItem=false" icon><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text>
<v-row>
<v-col cols="2">
<v-icon v-text="formItem.icon" required></v-icon>
</v-col>
<v-col cols="10">
<v-text-field
v-model="formItem.icon"
label="mdi icon"
outlined
clearable
required
></v-text-field>
</v-col>
</v-row>
<v-text-field v-model="formItem.title" label="아이템 이름" outlined hide-details></v-text-field>
</v-card-text>
</v-card>
</v-dialog>
<!-- 서브 아이템 수정 dialog -->
<v-dialog v-model="dialogSubItem" max-width="400">
<v-card>
<v-card-title>
서브 아이템 수정
<v-spacer></v-spacer>
<v-btn @click="saveSubItem" icon color=""><v-icon>mdi-content-save</v-icon></v-btn>
<v-btn @click="dialogSubItem=false" icon><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text>
<v-text-field v-model="formSubItem.title" label="메뉴 이름" outlined required></v-text-field>
<v-text-field v-model="formSubItem.to" label="경로" outlined required></v-text-field>
</v-card-text>
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
props: ['items'],
data () {
return {
dialogItem: false,
dialogSubItem: false,
selectedItemIndex: 0, // 메인 아이템 제어용 변수
selectedSubItemIndex: 0, // 서브 아이템 제어용 변수
formItem: {
icon: '',
title: ''
},
formSubItem: {
title: '',
to: ''
}
}
},
methods: {
async save () { // 전체 저장 함수
try {
const db = this.$firebaseDB.getDatabase()
await this.$firebaseDB.set(this.$firebaseDB.ref(db, 'site/'), { // 통째로 하기 때문에 update대신 set 사용
menu: this.items
})
} finally {
this.dialogItem = false // 메인 아이템 저장 후 창 닫기
this.dialogSubItem = false // 서브 아이템 저장 후 창 닫기
}
},
openDialogItem (index) { // 메인 아이템 dialog 함수
this.selectedItemIndex = index // 클릭한 dialog에 대한 index 기억하기
console.log(index)
if (index < 0) {
this.formItem.icon = 'mdi-crosshairs-question' // 새로 메뉴를 만들다면 비워두기
this.formItem.title = '' // 새로 메뉴를 만들다면 비워두기
} else {
this.formItem.icon = this.items[index].icon // 기존 메뉴라면 아이콘 이름 가져오기
console.log(this.items[index].icon)
this.formItem.title = this.items[index].title // 기존 메뉴라면 메뉴 이름 가져오기
}
this.dialogItem = true
},
async saveItem () { // 메인 아이템 저장 함수
if (this.selectedItemIndex < 0) {
this.items.push(this.formItem) // 현재 작성한 내용을 추가
} else {
this.items[this.selectedItemIndex].icon = this.formItem.icon // 현재 아이콘 가져오기
this.items[this.selectedItemIndex].title = this.formItem.title // 현재 제목 가져오기
}
this.save()
},
openDialogSubItem (index, subIndex) { // 서브 아이템 dialog 함수
this.selectedItemIndex = index // 클릭한 dialog에 대한 index 기억하기
this.selectedSubItemIndex = subIndex // 클릭한 dialog에 대한 subIndex 기억하기
if (subIndex < 0) {
this.formSubItem.title = '' // 새로 서브 메뉴를 만들다면 비워두기
this.formSubItem.to = '' // 새로 서브 메뉴를 만들다면 비워두기
} else {
this.formSubItem.title = this.items[index].subItems[subIndex].title // 기존 서브 메뉴라면 메뉴명 가져오기
this.formSubItem.to = this.items[index].subItems[subIndex].to // 기존 서브 메뉴라면 경로 가져오기
}
this.dialogSubItem = true
},
async saveSubItem () { // 서브 아이템 저장 함수
if (this.selectedSubItemIndex < 0) {
if (!this.items[this.selectedItemIndex].subItems) {
this.items[this.selectedItemIndex].subItems = []
}
this.items[this.selectedItemIndex].subItems.push({ title: this.formSubItem.title, to: this.formSubItem.to }) // 현재 작성한 내용을 추가
} else {
this.items[this.selectedItemIndex].subItems[this.selectedSubItemIndex].title = this.formSubItem.title // 현재 아이콘 가져오기
this.items[this.selectedItemIndex].subItems[this.selectedSubItemIndex].to = this.formItem.to // 현재 경로 가져오기
}
this.save()
}
}
}
</script>
<style>
</style>
- 코드가 점점 난잡해지고 있으나 어떻게 돌아가는지 이해하고 넘어가도록 하자.
- memi dev 유튜브 강의 보기
- https://memi.dev/board/lecture/1597406518842
- https://www.youtube.com/watch?v=Gjgd6No88mQ
21 하위메뉴 추가하기 : memi
하위메뉴 추가는 결국 상위메뉴와 같은 방법이지만..\n코드가 길어져서 가독성이 떨이지므로 코딩이 쉽지는 않습니다.\n코드를 보며 직접 만들어보며 감
memi.dev
해당 글은 [memi dev] 유튜브 채널을 토대로 공부한 내용을 기록하기 위하여 작성됨.