动态手风琴菜单

import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const activeIndexes = ref({});

    const menuItems = ref([
      { id: 1, title: '首页', children: [] },
      { id: 2, title: '产品管理', children: [
        { id: 21, title: '产品列表', children: [
          { id: 211, title: '产品详情', children: [
            { id: 2111, title: '详细规格', children: [] },
            { id: 2112, title: '用户评价', children: [] }
          ] },
          { id: 212, title: '产品分类', children: [] }
        ] },
        { id: 22, title: '添加产品', children: [] }
      ] },
      { id: 3, title: '订单管理', children: [
        { id: 31, title: '订单列表', children: [] },
        { id: 32, title: '退货管理', children: [] }
      ] },
      { id: 4, title: '用户管理', children: [
        { id: 41, title: '用户列表', children: [] },
        { id: 42, title: '权限管理', children: [] }
      ] }
    ]);

    const toggleMenu = (id, parentId = null) => {
      if (parentId) {
        Object.keys(activeIndexes.value).forEach((key) => {
          if (key.startsWith(parentId.toString()) && key !== id.toString()) {
            activeIndexes.value[key] = false;
          }
        });
      }
      activeIndexes.value[id] = !activeIndexes.value[id];
    };

    return {
      activeIndexes,
      menuItems,
      toggleMenu,
    };
  },
  template: `
    <div class="menu">
      <template v-for="item in menuItems" :key="item.id">
        <div class="menu-item" @click="toggleMenu(item.id)">
          {{ item.title }}
        </div>
        <transition name="slide">
          <div v-if="activeIndexes[item.id]" class="submenu">
            <template v-for="sub in item.children" :key="sub.id">
              <div class="submenu-item" @click="toggleMenu(sub.id, item.id)">
                {{ sub.title }}
              </div>
              <transition name="slide">
                <div v-if="activeIndexes[sub.id]" class="subsubmenu">
                  <template v-for="subsub in sub.children" :key="subsub.id">
                    <div class="subsubmenu-item" @click="toggleMenu(subsub.id, sub.id)">
                      {{ subsub.title }}
                    </div>
                    <transition name="slide">
                      <div v-if="activeIndexes[subsub.id]" class="subsubsubmenu">
                        <div v-for="subsubsub in subsub.children" :key="subsubsub.id" class="subsubsubmenu-item" @click="toggleMenu(subsubsub.id, subsub.id)">
                          {{ subsubsub.title }}
                        </div>
                      </div>
                    </transition>
                  </template>
                </div>
              </transition>
            </template>
          </div>
        </transition>
      </template>
    </div>
  `,
  style: `
    .menu {
      width: 200px;
      background: #2c3e50;
      color: white;
      padding: 10px;
    }
    .menu-item {
      padding: 10px;
      cursor: pointer;
      background: #34495e;
      margin-bottom: 5px;
    }
    .menu-item:hover {
      background: #1abc9c;
    }
    .submenu, .subsubmenu, .subsubsubmenu {
      padding-left: 20px;
      background: #3b4b5a;
      overflow: hidden;
    }
    .submenu-item, .subsubmenu-item, .subsubsubmenu-item {
      padding: 8px;
      cursor: pointer;
    }
    .submenu-item:hover, .subsubmenu-item:hover, .subsubsubmenu-item:hover {
      background: #16a085;
    }
    .slide-enter-active, .slide-leave-active {
      transition: max-height 0.3s ease-out, opacity 0.3s;
    }
    .slide-enter-from, .slide-leave-to {
      max-height: 0;
      opacity: 0;
    }
    .slide-enter-to, .slide-leave-from {
      max-height: 200px;
      opacity: 1;
    }
  `,
});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值