微人事项目学习之导航菜单加载

学习SpringBoot+Vue前后端分离项目,原项目GitHub地址,项目作者江雨一点雨博客。

安装和使用Vuex

命令行输入npm install vuex

npm install vuex

创建src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex' //导入Vuex

Vue.use(Vuex)

export default  new  Vuex.Store({
	// 定义属性
    state:{
    	//菜单信息存放
        routes:[]
    },
    //修改属性
    mutations:{
    	//调用时只需传data
        initRoutes(state,data){
            state.routes=data;
        }
    },
    //Action类似于mutation
	//Action 提交的是 mutation,而不是直接变更状态。
    //Action 可以包含任意异步操作。
    actions:{

    }
})

在main.js中引入vuex

import store from './store/index.js'

new Vue({
    router,
    store,
  render: h => h(App)
}).$mount('#app')

菜单请求工具类封装

创建src/utils/menus.js

import {getRequest} from "./api";
//创建菜单初始化方法  
export const initMenu=(router,store)=>{
	//判断是否有菜单数据,有就不加载
    if (store.state.routes.length>0){
        return;
    }
    getRequest("/system/config/menu").then(data=>{
        if (data){
            let fmtRoutes = formatRoutes(data);
            router.addRoutes(fmtRoutes);
            store.commit('initRoutes',fmtRoutes)
        }
    })
}

export const formatRoutes=(routes)=>{
    let fmRoutes=[];
    routes.forEach(router=>{
    	//批量定义,相当于let path=router.path
        let {
            path,
            component,
            name,
            meta,
            iconCls,
            children  //此处的children已经格式化了
        }=router;
        //判断是否是一级菜单的children
        if (children && children instanceof Array){
        	//递归
            children=formatRoutes(children);
        }
        let fmRouter={
            path:path,
            name:name,
            iconCls:iconCls,
            meta:meta,
            children:children,
            //动态加载
            component(resolve){
            	//Home开头
                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/per/' + component + '.vue'], resolve);
                }else if (component.startsWith("Sal")){
                    require(['../views/sal/' + component + '.vue'], resolve);
                }else if (component.startsWith("Sta")){
                    require(['../views/sta/' + component + '.vue'], resolve);
                }else if (component.startsWith("Sys")){
                    require(['../views/sys/' + component + '.vue'], resolve);
                }
            }
        }
        //fmRouter放入数组fmRoutes中
        fmRoutes.push(fmRouter);
    })
    return fmRoutes;
}

根据数据库中menu表创建包和文件,重复性工作。
微人事项目学习之导航菜单加载_第1张图片微人事项目学习之导航菜单加载_第2张图片
微人事项目学习之导航菜单加载_第3张图片
微人事项目学习之导航菜单加载_第4张图片

部署路由导航守卫

为了解决加载菜单信息一刷新就消失的问题(其实是initMenus就加载一次),部署路由导航守卫
vue官网文档
需要全局部署,放到main.js中

router.beforeEach((to, from, next) => {
   //判断要跳转的页面是否是登录页
   if (to.path=='/'){
     next();
   }else {
           initMenu(router,store);
           next();
  }
})

在Home.vue中添加computed属性

computed:{
          routes(){
              return this.$store.state.routes;
          }
},

修改el-submenu,因为routes已经在computed里面了。

<el-submenu :index="index+''" v-for="(item,index) in routes" v-if="!item.hidden" :key="index">

现在有一个小问题需要修改,当我们注销登录后,换另外一个用户登录,显示的还是上一个用户的菜单信息,刷新后才显示正确的信息。这是因为在注销登录时,没有清空store里面的信息。做如下修改,

commandHandler(cmd){
                if (cmd == 'logout'){
                    this.$confirm('此操作将注销登录, 是否继续?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(() => {
                        this.getRequest("/logout");
                        window.sessionStorage.removeItem("user");
                        this.$store.commit('initRoutes',[]);//清空
                        this.$router.replace("/");
                    }).catch(() => {
                        this.$message({
                            type: 'info',
                            message: '已取消操作'
                        });
                    });
                }
            }

首页完善

在首页添加面包屑:显示当前页面的路径,快速返回之前的任意页面。
直接从element-ui官网复制粘贴,修改代码

<el-main>            
					//如果当前为home页则不显示面包屑,否则继续        
                    <el-breadcrumb separator-class="el-icon-arrow-right" v-if="this.$router.currentRoute.path!='/home'">
                        <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
                        //获取当前路由的name属性
                        <el-breadcrumb-item>{{this.$router.currentRoute.name}}</el-breadcrumb-item>
                    </el-breadcrumb>
                    //首页显示
                    <div class="homeWelcome" v-if="this.$router.currentRoute.path=='/home'">
                        欢迎
                    </div>
                    <router-view class="homeRouterView"/>
                </el-main>

添加homeWelcone样式

.homeWelcome{
    text-align: center;
    font-size: 30px;
    font-family: 微软雅黑;
    color: darkorange;
    padding-top: 50px;
}

你可能感兴趣的:(微人事项目学习,spring,boot,vue.js)