-
21. Vue와 Firebase로 나만의 사이트 만들기 - 하위메뉴 추가하기개발 공부/VF 2025. 7. 1. 09:00반응형
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] 유튜브 채널을 토대로 공부한 내용을 기록하기 위하여 작성됨.
반응형'개발 공부 > VF' 카테고리의 다른 글
20. Vue와 Firebase로 나만의 사이트 만들기 - 메뉴 추가하기 (1) 2025.06.30 19. Vue와 Firebase로 나만의 사이트 만들기 - 에러 처리하기 (1) 2025.06.29 18. Vue와 Firebase로 나만의 사이트 만들기 - 푸터 수정해보기 (0) 2025.06.28 17. Vue와 Firebase로 나만의 사이트 만들기 - 제목 수정해보기 (1) 2025.06.27 16. Vue와 Firebase로 나만의 사이트 만들기 - realtime 쓰고 읽기 (7) 2025.06.26