vue3中使用antd-vue实现面包屑导航

该文描述了一个Vue应用中如何配置路由实现登录后默认选中第一个动态栏目,并在点击不同模块时动态更新面包屑导航标题。通过使用`router.ts`设置路由规则,以及在`Home.vue`组件中处理菜单的显示,利用`<a-menu>`和`<a-sub-menu>`组件动态生成菜单结构,同时通过`watch`监听路由变化来更新面包屑信息。
摘要由CSDN通过智能技术生成

期望的实现效果,登录后进入主页,默认选中第一个动态栏目,点击下面任意模块,右侧面包屑能够动态改变标题。

router.ts模块

const routes: RouteRecordRaw[] = [
  {
    path: "/",
    redirect: "/login",
  },
  {
    path: "/login",
    name: "login",
    component: () => import("../views/Login.vue"),
    children: [],
  },

  {
    path: "/home",
    name: "home",
    redirect: "/home/dynamic",
    component: () => import("../views/Home.vue"),
    children: [
      {
        path: "dynamic",
        meta: {
          title: ["动态"],
        },
        name: "dynamic",
        component: () => import("../views/routerCmp/dynamic.vue"),
      },
      {
        path: "buseness",
        name: "buseness",
        meta: {
          title: ["业务模块", "业务部功能使用情况"],
        },
        component: () => import("../views/routerCmp/buseness.vue"),
      },
      {
        path: "menuManage",
        name: "menuManage",
        meta: {
          title: ["系统模块", "菜单管理"],
        },
        component: () => import("../views/routerCmp/setting.vue"),
      },
    ],
  },
];

home.vue 

<template>
<a-layout style="min-height: 100vh">
      <a-layout-sider>
        <div class="logoBox"><div class="logo"></div></div>
        <a-menu
          theme="dark"
          mode="inline"
          v-model:selectedKeys="SelectedKey"
          :openKeys="openKeys"
          @click="handleClick"
        >
          <template v-for="item in cardList">
            <a-menu-item v-if="!item.children" :key="item.id">
              <router-link :to="item.path"
                ><div class="menustyle">
                  <span :class="IconType[item.id]"></span>
                  <span>{{ item.name }}</span>
                </div></router-link
              >
            </a-menu-item>
            <a-sub-menu v-else :key="item.path">
              <template #title>
                <div class="menustyle">
                  <span :class="IconType[item.id]"></span>
                  <span>{{ item.name }}</span>
                </div>
              </template>
              <a-menu-item :key="children.id" v-for="children in item.children"
                ><router-link :to="children.path">{{
                  children.name
                }}</router-link></a-menu-item
              >
            </a-sub-menu>
          </template>
        </a-menu>
      </a-layout-sider>
      <a-layout>
        <a-layout-header style="background: #fff" class="navTitle">
          <div class="titleBox">
            <a-breadcrumb>
              <a-breadcrumb-item v-for="item in breadCumber">{{
                item
              }}</a-breadcrumb-item>
            </a-breadcrumb>
            <div class="UserBox">
              <div class="userIcon"></div>
              <div>用户名</div>
              <div class="UserBoxhover">
                <div class="logout" @click="logoutFn">退出登录</div>
              </div>
            </div>
          </div>
        </a-layout-header>
        <a-layout-content class="layoutstyle">
          <div class="bodyContent"><router-view></router-view></div>
        </a-layout-content>
      </a-layout>
    </a-layout>
</template>
<script lang="ts" setup>
import { ElMessage } from "element-plus";
import { onMounted, ref, watch } from "vue";
import { getMenu } from "../api/home";
import { useRoute, useRouter } from "vue-router";
interface MenuType {
  name: string;
  parentId?: number;
  path: string;
  id: string;
}
const router = useRouter();
const menuList = ref<MenuType[]>();
const routes = useRoute();
const openKeys = ref<string[]>(
  sessionStorage.getItem("tabActive")
    ? JSON.parse(sessionStorage.getItem("tabActive") || "")
    : []
);
const breadCumber = ref(routes.meta.title);
const SelectedKey = ref<string[]>(
  sessionStorage.getItem("tabActive")
    ? JSON.parse(sessionStorage.getItem("tabActive") || "")
    : ["1"]
);
const IconType: { [key: string]: string } = {
  1: "dynamic",
  2: "buseness",
};

const handleClick = (e: any) => {
//防止刷新后状态重置
  SelectedKey.value = e.keyPath;
  openKeys.value = e.keyPath;
  sessionStorage.setItem("tabActive", JSON.stringify(e.keyPath));
};


//监听路由中的meta值改变
watch(
  () => routes.meta,
  () => {
    breadCumber.value = routes.meta.title;
  }
);
//模拟数据
const cardList = ref([
  { id: "1", name: "动态", path: "/home/dynamic" },
  {
    id: "2",
    name: "业务模块",
    path: "buseness",
    children: [{ id: "4", name: "业务部功能使用情况", path: "/home/buseness" }],
  },
  {
    id: "3",
    name: "系统模块",
    path: "setting",
    children: [
      {
        id: "5",
        name: "菜单管理",
        path: "/home/menuManage",
      },
    ],
  },
]);
</script>

 记录一下,当我去v-for左侧的菜单数组时,我需要在中间去判断是显示<a-sub-menu>还是<a-menu-item>,有子元素children就显示<a-sub-menu>,没有子元素就显示<a-menu-item>。

一开始,我给这两个元素的key值都是item.id,但这个时候虽然页面不报错,但代码会标红并且提示我只能有唯一key值,我只能在v-if的模块给item.id,在v-else的模块给item.path。

antd-vue中控制<a-sub-menu>是否展开是openKeys

默认选中是SelectedKey

路由跳转的地方我使用了router-link,也可以写单独的函数去router.push({name:'xxx',query:{ }})

其中query可以传递相关参数到目的页面

因为我的面包屑不要求实现点击跳转,仅仅作为文字展示,所有没有写相关跳转逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值