后台管理系统中的menu组件

接口:http://shiyansong.cn:8888/api/private/v1/menus

我采用的是vue3+vite+ts+pinia进行开发项目希望可以对你有所帮助。

<template>
  <div>
    <a-layout>
      <a-layout-header class="headerStyle">Header</a-layout-header>
      <a-layout>
        <a-layout-sider class="siderStyle">
          <!-- menu -->
          <a-menu
            v-model:selectedKeys="state.selectedKeys"
            :open-keys="state.openKeys"
            style="width: 256px"
            mode="inline"
            :items="state.items"
            @openChange="onOpenChange"
            @click="handleClick"
          />
          <!-- menu -->
        </a-layout-sider>
        <a-layout-content class="contentStyle"
          ><router-view></router-view
        ></a-layout-content>
      </a-layout>
    </a-layout>
  </div>
</template>

<script lang="ts" setup>
import { userState } from "@/store/menu";
import { storeToRefs } from "pinia";
const { onOpenChange, handleClick } = userState();
const { state } = storeToRefs(userState());
</script>
import { Service } from "./request";
// import { AxiosPromise } from "axios";
// 角色列表
export function menu(): Promise<icmenu> {
  return Service({
    url: "menus",
    method: "GET",
  });
}

interface icmenu {
  data: ismenu[];
  meta: ilmenu;
}
interface ilmenu {
  msg: string;
  status: number;
}
interface ismenu {
  key: string;
  authName: string;
  children: ibmenu[];
  id: number;
  order: number;
  path: string;
}
interface ibmenu {
  authName: string;
  children: any;
  id: number;
  order: null;
  path: string;
}
import { defineStore } from "pinia";
import { h, onMounted, reactive } from "vue";
import { useRouter } from "vue-router";
import {
  UserOutlined,
  KeyOutlined,
  ShoppingOutlined,
  ShoppingCartOutlined,
  ConsoleSqlOutlined,
  WifiOutlined,
  TeamOutlined,
  IdcardOutlined,
  LockOutlined,
  AppstoreOutlined,
  PartitionOutlined,
  BarsOutlined,
  SnippetsOutlined,
  LineChartOutlined,
} from "@ant-design/icons-vue";
import { menu } from "@/api/menu";
import { message } from "ant-design-vue";
import type { MenuProps } from "ant-design-vue";
export const userState = defineStore("users", () => {
  const router = useRouter();
  interface iItems {
    key: string;
    icon?: Function;
    label: string;
    title: string;
    children?: iItems[];
  }
  interface cc {
    selectedKeys: [];
    rootSubmenuKeys: string[];
    openKeys: string[];
    items: iItems[];
  }

  const state = reactive<cc>({
    selectedKeys: [],
    rootSubmenuKeys: [],
    openKeys: [sessionStorage.openKeys] || [],
    items: [],
  });
  const onOpenChange = (openKeys: string[]) => {
    const latestOpenKey = openKeys.find(
      (key) => state.openKeys.indexOf(key) === -1
    );
    if (state.rootSubmenuKeys.indexOf(latestOpenKey!) === -1) {
      state.openKeys = openKeys;
    } else {
      state.openKeys = latestOpenKey ? [latestOpenKey] : [];
    }

    sessionStorage.openKeys = state.openKeys;
  };
  const iconlist = [
    {
      icon: () => h(UserOutlined),
      child: [
        {
          icon: () => h(TeamOutlined),
        },
      ],
    },
    {
      icon: () => h(KeyOutlined),
      child: [
        {
          icon: () => h(IdcardOutlined),
        },
        {
          icon: () => h(LockOutlined),
        },
      ],
    },
    {
      icon: () => h(ShoppingOutlined),
      child: [
        {
          icon: () => h(AppstoreOutlined),
        },
        {
          icon: () => h(PartitionOutlined),
        },
        {
          icon: () => h(BarsOutlined),
        },
      ],
    },
    {
      icon: () => h(ShoppingCartOutlined),
      child: [
        {
          icon: () => h(SnippetsOutlined),
        },
      ],
    },
    {
      icon: () => h(ConsoleSqlOutlined),
      child: [
        {
          icon: () => h(LineChartOutlined),
        },
      ],
    },
  ];
  const menus = async () => {
    const {
      data,
      meta: { status },
    } = await menu();
    if (status === 200) {
      message.success("获取成功");
      data.map((item: any, index: number) => {
        // 里面的icon
        const iconitem = iconlist[index]["child"];
        state.rootSubmenuKeys.push(item.id + "");
        state.items.push({
          key: item.id + "_" + item.path,
          icon: iconlist[index]["icon"],
          label: item.authName,
          title: item.authName,
          children: item.children.map(
            (
              child: {
                path: string;
                id: string;
                authName: any;
              },
              childindex: number
            ) => {
              return {
                key: child.id + "_" + child.path,
                icon: iconitem
                  ? iconitem[childindex]["icon"]
                  : () => h(WifiOutlined),
                label: child.authName,
                title: child.authName,
              };
            }
          ),
        });
      });
    } else {
      message.error("获取失败");
    }
  };
  const handleClick: MenuProps["onClick"] = (menuInfo) => {
    // console.log("click ", menuInfo);
    // console.log("click ", (menuInfo.key as string).split("_")[1]);
    const path = (menuInfo.key as string).split("_")[1];
    router.push(`/${path}`);
  };
  onMounted(() => {
    menus();
  });
  return {
    state,
    onOpenChange,
    handleClick,
  };
});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值