动态的菜单页面和后端菜单接口交互

每个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>

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java语录精选

你的鼓励是我坚持下去的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值