1.问题之路由守卫
初写路由守卫,对于next()的理解不是很透彻,就想着都放行,不然看不到效果,结果控制台出现了警告,想着报黄的问题就不是问题,但仔细一看发现他说,如果再生产阶段就会失败,就觉得有必要解决一下
以下是我的代码
javascript
//路由鉴权
import router from "@/router"
import nprogress from "nprogress"
//引入进度条的样式
import "nprogress/nprogress.css"
//删除加载进度条傍边的小球
nprogress.configure({showSpinner:false})
//引入小仓库
import { store } from "@/stores/modules/user"
import pinia from "./stores" //在外部使用小仓库之前的引入大仓库,否则会报错,可以理解为仓库时通过大仓库的create而建立,没有引入大仓库,小仓库就不存在,而组件内是因为在main.ts中通过use()使用了
let useStore = store(pinia) //然后将pinia传进去
//console.log(useStore)
//全局守卫:项目当中任意路由切换都会触发的钩子
//全局前置首位
router.beforeEach(async (to: any, from: any, next: any) => {
//浏览器任务栏的名字
document.title = to.meta.title
//to:你将要访问的路由对象
//from:你从哪个路由而来
//next:路由的放行函数
//console.log(nprogress)
nprogress.start();
let token = useStore.token;
//获取用户信息
let userinfo = useStore.netName
//通过token来鉴别是否登录成功
if (token) {
//登录成功,不能访问login,指向首页
if (to.path == "/login") {
next({ path: '/' })
}
//登录成功访问其余几个路由
else {
//有用户信息
if (userinfo) {
//放行
next();
} else {
//如果没有用户信息,先获取用户信息再放行
try {
//获取用户信息
await useStore.userInfo()
//放行
next();
} catch (error) {
//token过期:获取不到用户信息
//用户手动修改了本地储存的token
//退出登录 用户相关的数据清空
useStore.userOutLogin();
next({ path: '/login', query: { redirect: to.path } })
}
}
}
} else {
if (to.path == '/login') {
next();
} else {
next({ path: '/login', query: { redirect: to.path } }) //返回登陆页面,并在地址栏中添加你想去的页面,登录成功后可以直接去
}
}
//问题所在
next();
})
//全局后置首位
router.afterEach(() => {
nprogress.done();
})
问题所在我特意加了很多空行,报黄的原因是路由导航执行了两次next函数,只要把最下面的next函数善删了就OK了
2.问题之el-menu
这个问题是我纯属眼瞎
以下是代码
javascript
<script setup lang='ts'>
import { ref, onMounted } from "vue"
import Menu from "../menu/test.vue"
//引入路由
import { useRouter } from "vue-router";
//获取路由器对象
let router = useRouter();
//接收路由数组
defineProps({
menuList: Object,
})
const goRouter = (item: any) => {
//路由跳转
router.push(item.index)
}
</script>
<template>
<div class="menu-container">
<template v-for="(item, index) in menuList">
<template v-if="!(item.meta as any).hidden">
<!-- 无子路由 -->
<el-menu-item :index="item.path" v-if="!item.children" @click="goRouter">
<template #title> <el-icon>
<component :is="(item.meta as any).icon">
</component>
</el-icon>
<span>{{ (item.meta as any).title }}</span>
</template>
</el-menu-item>
<!-- 仅一个子路由 -->
<el-menu-item :index="item.path" v-if="item.children && item.children.length == 1" @click="goRouter">
<template #title>
<el-icon>
<component :is="(item.children[0].meta as any).icon">
</component>
</el-icon>
<span>{{ (item.children[0].meta as any).title }}</span>
</template>
</el-menu-item>
<!-- 一子路由以上 -->
<el-sub-menu v-if="item.children && item.children.length > 1" :index="item.children[0].path">
<template #title>
<el-icon>
<component :is="(item.meta as any).icon">
</component>
</el-icon>
<span>{{ (item.meta as any).title }}</span>
</template>
<Menu :menuList="item.children"></Menu>
</el-sub-menu>
</template>
</template>
</div>
</template>
<style lang="less" scoped></style>
最后的页面,(折叠后的菜单)
预期的样子
产生的原因:将图标放到插槽title里面,导致图标和标题一起折叠,el-sub-menu与el-menu-item有些不一样,他的图标是放在插槽里的,也正是这个原因使搞混了,看文档一定要仔细,我因为这问题耽误了有近两个小时(还有一点是因为我不爱看文档,这毛病的改了)
解决:将图标放到外面
如:
javascript
<el-menu-item :index="item.path" v-if="!item.children" @click="goRouter">
<el-icon>
<component :is="(item.meta as any).icon">
</component>
</el-icon>
<template #title>
<span>{{ (item.meta as any).title }}</span>
</template>
</el-menu-item>
3.问题之内容区跳转
一般做某某管理系统,点击不同的菜单,内容区跳转到不同的内容路由,所以要跳转路由的一路由必须为主页的路由
如:
Kotlin
{
path: '/',
component: () => import('@/views/main/index.vue'), //这个路由为由组件拼成的主页面
name: '/',
meta: {
title: "",
hidden: false,
icon:'',
},
redirect:'/home',
children:[
{
path:'/home',
component: ()=> import('@/views/home/index.vue'),
name:'home',
meta:{
title: "首页",
hidden: false,
icon:'House'
}
}
]
}
,
{
path: '/goodsMange',
component: () => import('@/views/main/index.vue'), //第一次写的时候写了其他新建的文件一整个页面都跳了
name:'goodsMange',
meta:{
title:'商品管理',
hidden:false,
icon:'Goods',
},
redirect: '/goodsMange/SKU',
children: [
{
path: '/goodsMange/SKU',
component: ()=> import('@/views/goodsManage/SKU/index.vue'),
name:'sku',
meta:{
title:'SKU',
hidden:false,
icon:'Goods',
},
},
{
path: '/goodsMange/SPU',
component: ()=> import('@/views/goodsManage/SPU/index.vue'),
name:'spu',
meta:{
title:'SPU',
hidden:false,
icon:'Goods',
},
}
]
},