每个vue组件是独立的,现在把所有的数据变量保存在一个js文件
里,用插件npm install vuex --save
main.js
引入导航守卫
(全局前置守卫)相当于过滤器,每个页面跳转之前拦截请求
引入储存管理 store
管理数据
后端请求根据菜单页面规则跳转
各个请求工具方法utils.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
//注册变量存储
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
//引入请求api.js里面的请求方法
import {getRequest} from "./utils/api";
import {postRequest} from "./utils/api";
import {deleteRequest} from "./utils/api";
import {putRequest} from "./utils/api";
import {postKeyValueRequest} from "./utils/api";
//注册菜单页面跳转请求工具utils.js
import {initMenu} from "./utils/utils";
//请求封装到插件里,做全局
Vue.prototype.getRequest = getRequest;
Vue.prototype.postRequest = postRequest;
Vue.prototype.deleteRequest = deleteRequest;
Vue.prototype.putRequest = putRequest;
Vue.prototype.postKeyValueRequest = postKeyValueRequest;
/**
* 全局守卫前置 所有的页面跳转在这拦截,
* to 表示去哪里
* from 从哪里来的
* next 过滤器链 放过请求
*/
router.beforeEach((to, from, next) => {
if (to.path == '/') {
next();
}else{
if (window.sessionStorage.getItem("user")) {
initMenu(router, store);
next();
}else{
next('/');
}
}
})
Vue.config.productionTip = false
Vue.use(ElementUI);
new Vue({
router,
store, //存储
render: h => h(App)
}).$mount('#app')
index.js里保存公共存储的数据
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
//用Java来说是定义一个变量和set方法
export default new Vuex.Store({
state:{
menus:[]
},
mutations:{
initNenus(state,data){ //接受到utils.js里数据把这个data数据给数组menus保存
state.menus=data;
}
}
})
utils.js 根据后端数据的组件名跳到指定的前端组件页面
/**
* 1.去index.js拿到公共存储的这个Store.state.menus这个变量
* 2.大于0,是个普通的菜单按钮,方法不用重新加载
* 3.不是正常的跳转或按f5,就重新发送请求getRequest("/system/config/menus")
* 4.resp服务端返回的数组
* 5.formatRoutes 格式化数组变对象
* 5-1.formatRoutes = (routes)=>是服务端返回的数据
* 5-2.forEach 遍历let{ }里面的变量
* 5-3. if (children && children instanceof Array) 是否有其它数组子项
* 5-4 有遍历数组
* 6.遍历到数组的组件名跳到指定vue文件
* 7.遍历完返回fmRoutes数组(前端组件名字符串变对象)
* 8.fmRoutes数组里面的数据动态的加载到router里,点击就出现数据了
*/
import {getRequest} from './api'
/**
*
* @param router 服务端返回的值
* @param store index.js存储Store.state.menus登陆数据
*/
export const initMenu = (router, store)=> {
if (store.state.menus.length > 0) {
return;
}
getRequest("/system/config/menus").then(resp=> {
if (resp) {
let fmtRoutes = formatRoutes(resp);
router.addRoutes(fmtRoutes); //数组里面的数据动态的加载到router里,点击就出现数据了
store.commit('initMenus', fmtRoutes); //调用initMenus方法,把数组中数据传到公共存储数据的
}
})
}
export const formatRoutes = (routes)=> {
let fmRoutes = [];
routes.forEach(router=> {
let {
path,
component,
name,
iconcls,
children
} = router;
if (children && children instanceof Array) {
children = formatRoutes(children);
}
let fmRouter = {
path: path,
component(resolve){ //格式化的数组数据,组件名是Home跳到../views/Home.vue文件
if (component.startsWith("Home")) {
require(['../views/' + component + '.vue'], resolve)
} else if (component.startsWith("Emp")) {
require(['../views/emp/' + component + '.vue'], resolve)
} else if (component.startsWith("Per")) {
require(['../views/personnel/' + component + '.vue'], resolve)
} else if (component.startsWith("Sal")) {
require(['../views/salary/' + component + '.vue'], resolve)
} else if (component.startsWith("Sta")) {
require(['../views/statistics/' + component + '.vue'], resolve)
} else if (component.startsWith("Sys")) {
require(['../views/system/' + component + '.vue'], resolve)
} else if (component.startsWith("Food")) {
require(['../views/food/' + component + '.vue'], resolve)
}
},
name: name,
iconcls: iconcls,
children: children
};
fmRoutes.push(fmRouter);
})
return fmRoutes;
}
计算属性
1.从公共存储的数据中this.$store.state.menus获取到值
2.然后再for遍历到菜单中
Home.vue
<template>
<div>
<el-container>
<el-header style="display: flex;background-color: #409eff;align-items: center;justify-content:space-between">
<div style="font-size: 28px;font-family: 华文行楷">XXXX管理系统</div>
<el-dropdown style="cursor: pointer" @command="menuCud">
<span class="el-dropdown-link" style="display: flex;align-items: center">
{{user.name}}<i><img :src="user.userface" alt="" style="width: 48px;height: 48px;border-radius: 24px"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="usercenter">个人中心</el-dropdown-item>
<el-dropdown-item command="setting">设置</el-dropdown-item>
<el-dropdown-item command="logout">注销</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-header>
<el-container>
<el-aside width="200px">
<el-menu router>
<el-submenu :index="index" v-for="(item,index) in menus" :key="index" v-if="!item.hidden">
<template slot="title">
<i class="el-icon-location"></i>
<span>{{item.name}}</span>
</template>
<el-menu-item :index="child.path" v-for="(child,indexj) in item.children" :key="indexj">{{child.name}}</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<el-main>
<router-view/>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
// import {getRequest} from "../utils/api";
export default {
name: "Home",
data(){
return{
user:JSON.parse(window.sessionStorage.getItem("user")) //登陆后信息保存
}
},
/**
* 计算属性 从公共的js里面获取到数据,然后到上面for遍历
*/
computed:{
menus(){
return this.$store.state.menus;
}
},
methods:{
menuCud(cmd){
if (cmd == 'logout') {
this.$confirm('此操作将注销登陆, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.getRequest("/logout"); //调用api.js里get方法注销请求
window.sessionStorage.removeItem("user"); //删除数据
this.$store.commit('initMenus', []); //清空公共数据
this.$router.replace('/');
}).catch(() => {
this.$message({
type: 'info',
message: '已取消'
});
});
}
}
}
}
</script>
<style scoped>
</style>