功能11:实现面包屑功能
功能10:添加首页菜单项
功能9:退出登录功能
功能8:页面权限控制
功能7:路由全局前置守卫
功能6:动态添加路由记录
功能5:侧边栏菜单动态显示
功能4:首页使用Layout布局
功能3:点击登录按钮实现页面跳转
功能2:静态登录界面
功能1:创建前端项目
前言
在导航栏上显示当前页面路径的就是面包屑。它可以侧边栏菜单联动。
一.操作步骤
1.先问问AI,提供一些思路
AI思考了107秒
AI会给出一些可能要修改的问题点,根据AI给出的方向适当修改代码。
2.修改Sidebar.vue
给el-menu设置default-active和default-openeds属性。
<template><el-menu router :default-active="activeMenu" :default-openeds="openedMenus" class="el-menu-vertical" unique-opened><template v-for="item in menuData" :key="item.path"><MenuItem :item="item" :level="0" /></template></el-menu>
</template><script setup>
import { defineProps, computed } from 'vue';
import MenuItem from './MenuItem.vue';
import { useRoute } from 'vue-router';const route = useRoute()
defineProps({menuData: {type: Array,required: true}
});const activeMenu = computed(() => {return route.path
})const openedMenus = computed(() => {return route.matched.map(item => item.path).filter(path => path !== '/')
})
</script>
3.修改Navbar.vue
style部分没有改变,不贴代码了。
<template><el-header class="navbar"><el-breadcrumb separator="/"><el-breadcrumb-item v-for="(item, index) in breadcrumbItems" :key="item.path"><router-link v-if="index === 0" :to="item.path">{{ item.meta.title }}</router-link><span v-else>{{ item.meta.title }}</span></el-breadcrumb-item></el-breadcrumb><div class="user-menu"><el-dropdown trigger="hover"><div class="avatar-container"><img :src="avatarUrl" alt="用户头像" class="avatar-image" /></div><template #dropdown><el-dropdown-menu class="dropdown-menu"><el-dropdown-item @click="handleSettings" class="menu-item"><span>个人设置</span></el-dropdown-item><el-dropdown-item divided @click="handleLogout" class="menu-item"><span>退出登录</span></el-dropdown-item></el-dropdown-menu></template></el-dropdown></div></el-header>
</template><script setup>
import { ElMessageBox } from 'element-plus'
import { computed } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()const breadcrumbItems = computed(() => {// 获取当前路由的匹配数组,过滤无meta的路由const matched = route.matched.filter(item => item.meta?.title);// 确保首页始终在首位(如果当前路由不是首页)if (route.path !== '/' && matched[0]?.path !== '/') {matched.unshift({ path: '/index', meta: { title: '首页' } });}if (route.path === '/' || route.path === '/index') {matched.splice(0, matched.length - 1)}return matched;
})// 请确保在 assets 目录下存在 user-avatar.png 图片文件
const avatarUrl = new URL('@/assets/images/profile.jpg', import.meta.url).hrefimport useUserStore from '@/stores/user'
const userStore = useUserStore()const handleLogout = () => {// 处理退出登录逻辑ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {userStore.logout().then(() => {location.href = '/index';})}).catch(() => { });
}const handleSettings = () => {// 处理设置逻辑console.log('打开设置页面')
}
</script>
4.修改MenuItem.vue
优先处理跟目录,返回/index,跟menu里的一致,组件才能正常联动。
const resolvePath = (routePath) => {if (routePath === '/') {return '/index'}if (props.basePath.length === 0) {return routePath}return getNormalPath(props.basePath + '/' + routePath)
}
后端返回的路由数据里的图标,有些是ElemetPlus里没有的,导致不显示,暂时先全部显示成主页图标House,方便观察菜单的层级关系。
<el-icon v-if="item.meta?.icon"><component is="House" /></el-icon>
二.功能验证
运行项目,浏览器访问http://localhost:5173/index
三.知识点拓展
四.思考
遗留一个Bug,在点击系统管理--日志管理--操作日志
菜单时,在面包屑上只显示了首页/系统管理/操作日志
。