router版本的错误,要么换版本,要么catch不处理
router里面添加
// 处理路由跳转的异常提示: 功能上没有问题的, 要么换3.0版本, 要么catch一下不处理不报错
const routerPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return routerPush.call(this, location).catch(error=> error)
}
1 不存在的页面 添加404,router-> index.js
{
path:'/404',
name:'NotFound',
component:()=> import('../views/404.vue') // 懒加载
},
// {
// path:'*',
// redirect:{ name:'NotFound'}
// },
异步路由无法匹配
100行添加
asyncRoutes.push({
path:'*',
redirect:{ name:'NotFound'}
})
- redirect
- async
2 添加401 非法的ajax请求
Notification
// 603 代表token失效, 处理跳转到权限不足页面
console.log(response,'res',response?.data?.code)
if (response?.data?.code === 603) { // token失效
Notification.error({
title: '错误',
message: 'token失效,请重新登录'
});
// 替换到401页面
router.replace('/401');
}
62行
export const pretty = function(promise) {
return promise.then(data=>[data,undefined])
.catch(err=>[undefined,err]);
}
element-ui contianer容器
layout->layout.vue
URL:http://localhost:8081/#/loan-input/index
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-container>
<el-header>Header</el-header>
<el-main>Main</el-main>
<el-footer>Footer</el-footer>
</el-container>
</el-container>
样式
<style>
.el-header, .el-footer {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
background-color: #E9EEF3;
color: #333;
text-align: center;
line-height: 160px;
}
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
</style>
删除
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
添加:
.el-container {
height: 100%;
}
<el-main>Main</el-main> 换Main
<router-view />
// view里面取出来的辅助函数 mapGetter
import { mapGetters,mapActions } from 'vuex'
computed: {
...mapGetters({
menus: 'user/getUserMenus'
})
},
添加菜单
aside里面添加
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
建立一个GAsindeMenu.vue,删除上述代码,复制
layout里面删除
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
layout里面添加
import GAsideMenu from '@/components/GAsideMenu';
<GAsideMenu v-for="(item, i) in menus" :key="i" :item="item" /> //循环数组,数据
components: { GAsideMenu }, // 声明组件
GAsindeMenu.vue里面
export default {
name:'GAsideMenu', // 递归组件的核心
props:{
item:{
type:Object,
required:true
}
}
}
<el-menu-item index="3" disabled> //disabled去掉
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
上面被替换,:index="item.path"唯一标识
v-if v-else 如果… 那么…
<el-menu-item v-if="!item.children" :index="item.path">
<!-- <i class="el-icon-document"></i> 可以通过配置传递icon -->
<span slot="title">{{item?.meta?.title}}</span>
</el-menu-item>
<el-submenu v-else :index="item.path">
<template #title>{{item?.meta?.title}}</template>
<GAsideMenu v-for="(it,i) in item.children" :key="i" :item="it"/>
</el-submenu>
删除空白菜单
menu.json修改
{
"path": "/",
"redirect":"/home",
"component":"Layout",
"meta":{
"title":"首页"
},
"children":[
{
"path":"/home",
"component":"Home"
}
]
},
改成
{
"path": "/",
"meta":{
"title":"首页"
}
},
router->index.js修改
{
path: '/',
redirect:'/home',
name: 'Home',
meta:{
title:'首页'
},
component: Layout,
children:[
{
path:'/home',
component:Home
}
]
},
添加面包屑
一个div包两个div,element-ui添加面包屑
<div>
<div class="left">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item><a href="/">活动管理</a></el-breadcrumb-item>
<el-breadcrumb-item>活动列表</el-breadcrumb-item>
<el-breadcrumb-item>活动详情</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="right"></div>
</div>
样式
.el-header {
display: flex;
align-items: center;
justify-content: space-between; // 挨着两边
}
建立一个组件GBreadcrumb.vue
在layout.vue中
import GBreadcrumb from '@/components/GBreadcrumb';
//声明组件
components: { GAsideMenu, GBreadcrumb },
//在left的div上加入
<GBreadcrumb />
建立一个组件GBreadcrumb.vue
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item v-for="(route, i) in breadcrumbList" :key="i">
<span v-if="breadcrumbList.length - 1 === i">{{ route?.meta?.title }}</span>
<router-link v-else :to="route">{{ route?.meta?.title }}</router-link>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
name: 'GBreadcrumb',
// v3
computed:{
breadcrumbList(){
return this.$route.matched.filter(route => route?.meta?.title);
}
},
// data() {
// return {
// breadcrumbList: []
// }
// },
// created(){
// this.breadcrumbList = this.$route.matched.filter(route => route?.meta?.title);
// },
// watch: { // 监视里有
// $route: {
// deep: true,
// handler() {
// console.log(this.$route.matched, 'this.$route.matched')
// this.breadcrumbList = this.$route.matched.filter(route => route?.meta?.title);
// },
// immediate:true, // v2 去掉created
// }
// },
}
</script>
<style>
</style>
v-for 循环遍历,
封装组件GDropdown.vue
<template>
<el-dropdown @command="$emit('command',$event)">
<span class="el-dropdown-link">
{{title}}<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="(item,i) in items" :command="item.key">{{ item.label }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
name:'GDropdown',
// methods:{
// xx(e){
// this.$emit('command',e);
// }
// },
props: {
title: {
required: true,
type: String
},
items: {
type: Array,
required: true,
}
}
}
</script>
<style>
</style>
GDropdown使用
import GDropdown from '@/components/GDropdown';
components: { GAsideMenu,GBreadcrumb,GDropdown },
<GDropdown @command="doCommand" :title="'admin'" :items="[{ key: 'logout', label: '退出' }]" />
不懂的知识点:
- props
- v-for
- computed
退出
modules->user.js
import {logout} from '@/apis/user';
import { Message } from 'element-ui';
actions:{
async doLogout({ commit,dispatch },payload){
let [res,err] = await logout();
// 清除各种数据
if (err) {
return Message.error('退出失败!!');
}
// 如果是使用dispatch异步action,也可以使用await
commit('changeIsLogin',false);
commit('changeUserInfo',null);
commit('changeUserMenus',null);
// 清空本地存储
window.sessionStorage.setItem('token','');
}
}
layout.vue
methods: {
...mapActions({
doLogout:'user/doLogout'
}),
async doCommand(e) {
if (e === 'logout') {
let [res,err] = await this.doLogout();
// 外部没有依赖里面的值
// 依赖的是执行顺序
window.location.reload();
}
}
},