目录
一、整体布局页Manage.vue
实现菜单展开和收缩、全局用户信息
<template>
<el-container style="min-height: 100vh;">
<el-aside :width="sideWidth + 'px'" style="box-shadow: 2px 0 6px rgb(0, 21, 41 / 35%);">
<Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow" />
</el-aside>
<el-container>
<el-header style="border-bottom: 1px solid #ccc;">
<Header :collapseBtnClass="collapseBtnClass" :collapse="collapse" :user="user" />
</el-header>
<el-main>
<!-- 当前页面的子路由在当前位置显示 -->
<router-view @refreshUser="getUser" />
</el-main>
</el-container>
</el-container>
</template>
<script>
import Aside from '@/components/Aside.vue'
import Header from '@/components/Header.vue'
export default {
data() {
return {
collapseBtnClass: 'el-icon-s-fold',
isCollapse: false,
sideWidth: 200,
logoTextShow: true,
user: {}
};
},
components: {
Aside,
Header
},
created() {
//从后台取最新数据
this.getUser()
},
methods: {
collapse() {
this.isCollapse = !this.isCollapse;
if (this.isCollapse) { //收缩
this.sideWidth = 64;
this.collapseBtnClass = 'el-icon-s-unfold';
this.logoTextShow = false;
}
else { //展开
this.sideWidth = 200;
this.collapseBtnClass = 'el-icon-s-fold';
this.logoTextShow = true;
}
},
getUser() {
let username = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")).username : ""
this.request.get("/user/username/" + username).then(res => {
//重新赋值
this.user = res.data
})
}
}
}
</script>
<style>
.el-header {
background-color: #fff;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
二、菜单组件Aside.vue
实现菜单默认展开,全局菜单列表
<template>
<el-menu :default-openeds="opens" style="min-height:100% overflow-x:hidden" background-color="rgb(48,65,86)"
text-color="#fff" active-text-color="#ffd04b" :collapse-transition="false" :collapse="isCollapse" router>
<div style="height: 60px;line-height: 60px;text-align: center;">
<img src="../assets/logo.png" alt="" style="width: 20px;position: relative; top: 5px;margin-right: 5px;">
<b style="color: white;" v-show="logoTextShow">后台管理系统</b>
</div>
<div v-for="item in menus" :key="item.id">
<div v-if="item.path">
<el-menu-item :index="item.path">
<i :class="item.icon"></i>
<span slot="title">{{ item.name }}</span>
</el-menu-item>
</div>
<div v-else>
<el-submenu :index="item.id + ''">
<template slot="title">
<i :class="item.icon"></i>
<span slot="title">{{ item.name }}</span>
</template>
<div v-for="subItem in item.children" :key="subItem.id">
<el-menu-item :index="subItem.path">
<i :class="subItem.icon"></i>
<span slot="title">{{ subItem.name }}</span>
</el-menu-item>
</div>
</el-submenu>
</div>
</div>
</el-menu>
</template>
<script>
export default {
name: "Aside",
props: {
isCollapse: Boolean,
logoTextShow: Boolean
},
data() {
return {
menus: localStorage.getItem("menus") ? JSON.parse(localStorage.getItem("menus")) : [],
opens: localStorage.getItem("menus") ? JSON.parse(localStorage.getItem("menus")).map(v => v.id + '') : []
}
}
}
</script>
三、头部组件Header.vue
面包屑导航(全局状态变量实现兄弟组件信息传递)、全局用户信息
<template >
<div style="line-height: 60px; desplay:flex ">
<div stype="flex: 1;">
<span :class="collapseBtnClass" style="cursor: pointer; font-size: 18px" @click="collapse"></span>
<el-breadcrumb separator="/" style="display: inline-block; margin-left: 10px;">
<el-breadcrumb-item :to="'/'">首页</el-breadcrumb-item>
<el-breadcrumb-item>{{ currentPathName }}</el-breadcrumb-item>
</el-breadcrumb>
<el-dropdown style="width: 150px; cursor: pointer; text-align: right; margin-right: 5px;">
<div style="display: inline-block">
<img :src="user.avatorUrl" alt=""
style="width: 50px;border-radius: 50%;position: relative;top: 10px;right: 5px;" />
<span>{{ user.nickname }}</span><i class="el-icon-arrow-down" style="margin-right: 5px;"></i>
</div>
<el-dropdown-menu slot="dropdown" style="width: 100px; text-align: center">
<el-dropdown-item style="font-size: 14px; padding: 5px 0;">
<router-link to="/person">个人信息</router-link>
</el-dropdown-item>
<el-dropdown-item style="font-size: 14px; padding: 5px 0;">
<router-link to="/password">修改密码</router-link>
</el-dropdown-item>
<el-dropdown-item style="font-size: 14px; padding: 5px 0;">
<span style="text-decoration: none;" @click="logout">退出</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import store from '@/store'
export default {
name: "Header",
data() {
return {
// user:localStorage.getItem("user")?JSON.parse(localStorage.getItem("user")):{}
}
},
props: {
collapseBtnClass: String,
collapse: Function,
user: Object
},
computed: {
currentPathName() {
return store.state.currentPathName
},
},
methods: {
logout() {
store.commit("logOut")
this.$message.success("退出成功")
}
},
watch: {
currentPathName(newVal, oldVal) {
console.log(newVal);
}
}
}
</script>
全局状态
import Vue from 'vue'
import Vuex from 'vuex'
import router, { resetRouter } from '@/router'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
currentPathName: ''
},
mutations: {
setPath(state) {
state.currentPathName = localStorage.getItem("currentPathName")
},
logOut() {
localStorage.removeItem("user")
localStorage.removeItem("menus")
router.push('/login')
//重置路由
resetRouter()
}
}
})
export default store