류윤주 류윤주 05-12
250512 류윤주 메뉴 재귀 수정
@c6d6567614e22a62581e7e83fe23095eeb5b4432
client/resources/scss/admin/layout.scss
--- client/resources/scss/admin/layout.scss
+++ client/resources/scss/admin/layout.scss
@@ -1,7 +1,7 @@
 .admin-wrap {
     background-color: #eaeff4;
     display: grid;
-    grid-template-columns: clamp(240px, 10vw, 450px) minmax(1020px, 1fr);
+    grid-template-columns: clamp(280px, 10vw, 450px) minmax(1020px, 1fr);
     grid-template-rows: 60px minmax(851px, 1226px);
     grid-template-areas:
         "sidebar header "
@@ -76,32 +76,20 @@
             height: calc(100% - 60px);
             /* 메뉴 스타일 */
             .main-menu {
-                padding: 2rem 0;
+                padding: 2rem;
                 height: 100%;
                 overflow-y: auto;
-                .menu-item {
-                    position: relative;
-                    cursor: pointer;
-                    padding: 0 2rem;
-    
-                    span{
+
+                    .has-children{
+                        position: relative;
                         display: block;
                         padding: 1rem;
-    
-                        &.main-active{
-                            color: var(--tk-main-50);
-                            font-weight: 700;
-
-                        }
-                    }
-                    
-                    >span.has-children{
-                        position: relative;
+                        cursor: pointer;
 
                         &::after {
                             content: '';
                             position: absolute;
-                            right: 0;
+                            right: 1rem;
                             top: 50%;
                             transform: translateY(-50%);
                             width: 20px;
@@ -113,13 +101,25 @@
                             border-radius: 50%;
                             transition: transform 0.3s ease;
                         }
-                    
+
                         &.open::after {
                             border: 1px solid var(--tk-main-50);
                             background-image: url(#{$url}/component/common/ico_arr_16_right_green70.svg);
                             transform: translateY(-50%) rotate(90deg); // 오른쪽 화살표 → 아래 방향
                     
                         }
+
+                        &.menu-active{
+                            color: var(--tk-main-50);
+                            font-weight: 700;
+
+                            
+
+                        }
+
+                        
+
+                        
                     }
     
                     /* 서브메뉴 스타일 */
@@ -132,8 +132,12 @@
                         width: 100%;
     
                         >li{
-    
                             cursor: pointer;
+
+                            span{
+                                display: block;
+                                padding: 1rem;
+                            }
     
                             &.sub-active{
                                 >span{
@@ -145,20 +149,9 @@
                             }
     
     
-                            &.has-third-depth{
-                                &.sub-active {
-                                    >span{
-                                        background-color: var(--tk-main-50);
-                                        color: var(--tk-white);
-                                        font-weight: 700;
-                                        @include radius(10);
-                                        // border-radius: 1rem 1rem 0 0;
-                                    }
-                                }
+                           
     
-                            }
-    
-                            .ssub-menu{
+                            >.sub-menu{
                                 padding: 1rem;
                                 background-color: var(--tk-gray-10);
                                 @include radius(10);
@@ -175,7 +168,7 @@
                         }
                     }
     
-                }
+
             }
         }
     }
 
client/views/component/menu/MenuItem.vue (added)
+++ client/views/component/menu/MenuItem.vue
@@ -0,0 +1,53 @@
+<template>
+  <li>
+    <span
+      @click.stop="handleClick"
+      :class="{
+        'has-children': menu.childList && menu.childList.length > 0,
+        'menu-active': isActive(menu.menuId),
+        'open': menu.isOpen,
+      }"
+    >
+      {{ menu.menuNm }}
+    </span>
+
+    <ul v-if="menu.isOpen && menu.childList?.length > 0" class="sub-menu">
+      <MenuItem
+        v-for="(child, idx) in menu.childList"
+        :key="idx"
+        :menu="child"
+        :is-active="isActive"
+        :on-click="onClick"
+        @toggle="onToggle"
+      />
+    </ul>
+  </li>
+</template>
+
+<script>
+export default {
+  name: "MenuItem",
+  props: {
+    menu: Object,
+    isActive: Function,
+    onClick: Function,
+  },
+  methods: {
+    handleClick() {
+      if (this.menu.childList && this.menu.childList.length > 0) {
+        // const updatedMenu = {
+        //   ...this.menu,
+        //   isOpen: !this.menu.isOpen,
+        // };
+        // console.log("updatedMenu",updatedMenu)
+        this.$emit("toggle", this.menu);
+      } else {
+        this.onClick(this.menu);
+      }
+    },
+    onToggle(menu) {
+      this.$emit("toggle", menu);
+    },
+  },
+};
+</script>
client/views/layout/AdminMenu.vue
--- client/views/layout/AdminMenu.vue
+++ client/views/layout/AdminMenu.vue
@@ -1,4 +1,4 @@
-<template>
+<!-- <template>
     <div class="side-bar">
         <div class="logo">
             <router-link :to="{path : this.$filters.ctxPath('/adm/main.page')}">ADMINISTRATOR</router-link>
@@ -32,7 +32,26 @@
             </ul>
         </nav>
     </div>
-</template>
+</template> -->
+<template>
+    <div class="side-bar">
+      <div class="logo">
+        <router-link :to="{ path: $filters.ctxPath('/adm/main.page') }">ADMINISTRATOR</router-link>
+      </div>
+      <nav>
+        <ul class="main-menu">
+            <MenuItem
+                v-for="(menu, idx) in menuList"
+                :key="idx"
+                :menu="menu"
+                :is-active="isActive"
+                :on-click="menuClick"
+                @toggle="toggleSubMenu"
+                />
+        </ul>
+      </nav>
+    </div>
+  </template>
 
 <script>
 import store from "../pages/AppStore";
@@ -40,6 +59,7 @@
 import { defaultSearchParams } from '../../resources/js/defaultSearchParams';
 import cntnStatsSave from "../../resources/js/cntnStatsSave";
 import { findBySysMenu } from '../../resources/api/menu';
+import MenuItem from "../component/menu/MenuItem.vue";
 
 export default {
     mixins: [queryParams, cntnStatsSave],
@@ -51,6 +71,9 @@
             menuList: [],
             activeMenus: [] // 현재 선택된 메뉴 및 부모 메뉴 ID 저장
         };
+    },
+    components:{
+        MenuItem
     },
     created() {
         this.findAll();
@@ -115,9 +138,11 @@
             }
         },
         toggleSubMenu(menu) {
+            console.log("toggleSubMenu",menu)
             if (menu.childList && menu.childList.length > 0) {
                 // 부모 메뉴 클릭 시 펼치기만 함
                 menu.isOpen = !menu.isOpen;
+                console.log(menu.isOpen)
             } else {
                 if(menu.routerUrl === "") {
                     // 하위메뉴가 없는 상위메뉴일 시 알림 출력
Add a comment
List