0
点赞
收藏
分享

微信扫一扫

串的定义及BF算法

_LEON_ 2024-03-05 阅读 48

动态路由实现左侧菜单导航

一、动态菜单创建

在前文中,router/index.js下方的3条子路由,假设后端只返回menu1和menu2这2条,也就是这路由,我们只需动态创建2条即可。
在这里插入图片描述

  1. 原来的 menu_data 使用mockjs来返回,模拟后台查询菜单数据返回
    • 在mockjs中定义对象的 /post/menuList 路径get请求
    • 返回参数中除了原来的 name、icon、path 增加了component,用于定义跳转路径。

mock/index.js代码

Mock.mock('/post/menuList', 'get', function () {
  const menu_data = [
    {
      name: '一级菜单1',
      icon: 'el-icon-location',
      path: '/index/menu1',
      component: 'Main1'
    },
    {
      name: '一级菜单2',
      icon: 'el-icon-document',
      path: '/index/menu2',
      component: 'Main2'
    }
  ]
  return {
    menu_data
  }
});
  1. 修改store/index.js,全部参考代码如下
    在这里插入图片描述
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './module/moduleA.js';
import moduleB from './module/moduleB.js';

Vue.use(Vuex)

const state = {
  username: '牛牛',
  userState: 0,
  menu_data: []
}
const mutations = {
  setUser(state, name) {
    state.username = name
  },
  setUserState(state, data) {
    state.userState += data
  },
  setMenuData(state, data) {
    state.menu_data = data
  },
}
const getters = {
  getUserState(state) {
    let data;
    if (state.userState == 0) {
      data = '无效'
    } else {
      data = state.userState + '级'
    }
    return data;
  }
}
const modules = {
  a: moduleA,
  b: moduleB
}

export default new Vuex.Store({
  state,
  mutations,
  getters,
  modules
})
  1. router/index.js 里面使用方法 beforeEach 来获取数据,并提交到store

在这里插入图片描述

import VueRouter from "vue-router"
import Index from "@/components/Index";
import axios from "axios";
import store from "@/store/index.js";

const routes = [
    //一级路由
    {
        path: '/index',
        name: 'index',
        component: Index,
        redirect: 'index/Main',
        //路由嵌套
        children:[
            {path: '/index/Main',component: () => import('@/components/Main/index.vue')},
            {path: '/index/menu1',component: () => import('@/components/Main/Main1.vue')},
            {path: '/index/menu2',component: () => import('@/components/Main/Main2.vue')},
            {path: '/index/menu3',component: () => import('@/components/Main/Main3.vue')}
        ]
    }
]
const router = new VueRouter({
    mode:'history',
    routes
})
router.beforeEach((to, from, next)=>{
    next();
    axios.get('/post/menuList').then(res=>{
         store.commit('setMenuData',res.data.menu_data)
    });
})
export  default router;
  1. Aside.vue 代码中,data里面的属性menu_data不能直接返回了,需通过computed来返回,并且返回的值是从store里面获取的

Aside.vue 参考代码如下

<template>
  <div style="height: 100%">
    <el-menu
      background-color="#545c64"
      text-color="#ffffff"
      active-text-color="#ffd04b"
      class="el-menu-vertical-demo"
      router
    >
      <el-menu-item
        :index="item.path"
        v-for="item in menu_data"
        :key="item.name"
      >
        <i :class="item.icon"></i>{{ item.name }}
      </el-menu-item>
    </el-menu>
  </div>
</template>

<script>
export default {
  name: "Aside",
  data() {
    return {};
  },
  computed: {
    menu_data: {
      get() {
        return this.$store.state.menu_data;
      },
    },
  },
};
</script>

<style scoped>
.el-icon-location,
.el-icon-document,
.el-icon-setting {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
</style>

页面效果
在这里插入图片描述

在这里插入图片描述

二、根据菜单数据来创建路由

目前的路由写法

const routes = [
    //一级路由
    {
        path: '/index',
        name: 'index',
        component: Index,
        redirect: 'index/Main',
        //路由嵌套
        children:[
            {path: '/index/Main',component: () => import('@/components/Main/index.vue')},
            {path: '/index/menu1',component: () => import('@/components/Main/Main1.vue')},
            {path: '/index/menu2',component: () => import('@/components/Main/Main2.vue')},
            {path: '/index/menu3',component: () => import('@/components/Main/Main3.vue')}
        ]
    }
]

针对上面的情况,我们可以考虑,通过菜单取到的数据,动态添加这个路由,而不是直接写死。

说干就干!!!

  1. 先将router/index.js这3条路由代码删除
const routes = [
    //一级路由
    {
        path: '/index',
        name: 'index',
        component: Index,
        redirect: 'index/Main',
        //路由嵌套
        children:[
            {path: '/index/Main',component: () => import('@/components/Main/index.vue')},
        ]
    }
]
  1. router/index.js 中创建添加动态路由的方法 buildRouter
let oRouters = router.options.routes;
const buildRouter = () => {
    let data = store.state.menu_data;
    data.forEach(item => {
        let new_router = {
            path: item.path,
            component: () => import('../components/Main/' + item.component + '.vue')
        }
        oRouters[0].children.push(new_router);
    })
    router.addRoutes(oRouters)
}
  1. 在创建动态菜单的同时调用这个函数,修改 router/index.js
router.beforeEach((to, from, next)=>{
    next();
    axios.get('/post/menuList').then(res=>{
         store.commit('setMenuData',res.data.menu_data);

        //动态创建路由
        buildRouter();
    });
})

页面展示,点击访问 index/menu1index/menu2正常
在这里插入图片描述

访问 index/menu3 就不会出现页面内容
在这里插入图片描述
全部参考代码

router/index.js

import VueRouter from "vue-router"
import Index from "@/components/Index";
import axios from "axios";
import store from "@/store/index.js";

const routes = [
    //一级路由
    {
        path: '/index',
        name: 'index',
        component: Index,
        redirect: 'index/Main',
        //路由嵌套
        children: [
            { path: '/index/Main', component: () => import('@/components/Main/index.vue') },
        ]
    }
]

const router = new VueRouter({
    mode: 'history',
    routes
})

let oRouters = router.options.routes;
const buildRouter = () => {
    let data = store.state.menu_data;
    data.forEach(item => {
        let new_router = {
            path: item.path,
            component: () => import('../components/Main/' + item.component + '.vue')
        }
        oRouters[0].children.push(new_router);
    })
    router.addRoutes(oRouters)
}

router.beforeEach((to, from, next) => {
    next();
    axios.get('/post/menuList').then(res => {
        store.commit('setMenuData', res.data.menu_data);

        //动态创建路由
        buildRouter();
    });
})

export default router;

三、添加路由已加载标记,省的每次点击菜单都要加载

  1. 修改 store/index.js,在store.js的state添加 属性isLoadRoute: false
    在这里插入图片描述
  2. router/index.js 添加路由的 router.beforeEach 稍作修改
    在这里插入图片描述

store和router的相关代码如下

store/index.js代码

import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './module/moduleA.js';
import moduleB from './module/moduleB.js';

Vue.use(Vuex)

const state = {
  username: '牛牛',
  userState: 0,
  menu_data: [],
  isLoadRoute: false,
}
const mutations = {
  setLoadRoute(state, data) {
    state.isLoadRoute = data
  },
  setUser(state, name) {
    state.username = name
  },
  setUserState(state, data) {
    state.userState += data
  },
  setMenuData(state, data) {
    state.menu_data = data
  },

}
const getters = {
  getUserState(state) {
    let data;
    if (state.userState == 0) {
      data = '无效'
    } else {
      data = state.userState + '级'
    }
    return data;
  }
}
const modules = {
  a: moduleA,
  b: moduleB
}

export default new Vuex.Store({
  state,
  mutations,
  getters,
  modules
})

router/index.js代码

import VueRouter from "vue-router"
import Index from "@/components/Index";
import axios from "axios";
import store from "@/store/index.js";

const routes = [
    //一级路由
    {
        path: '/index',
        name: 'index',
        component: Index,
        redirect: 'index/Main',
        //路由嵌套
        children: [
            { path: '/index/Main', component: () => import('@/components/Main/index.vue') },
        ]
    }
]

const router = new VueRouter({
    mode: 'history',
    routes
})

let oRouters = router.options.routes;
const buildRouter = () => {
    let data = store.state.menu_data;
    data.forEach(item => {
        let new_router = {
            path: item.path,
            component: () => import('../components/Main/' + item.component + '.vue')
        }
        oRouters[0].children.push(new_router);
    })
    router.addRoutes(oRouters)
}

router.beforeEach((to, from, next) => {
    //判断路由是否已经加载过
    let isLoadRoute = store.state.isLoadRoute;
    if (!isLoadRoute) {
        axios.get('/post/menuList').then(res => {
            store.commit('setMenuData', res.data.menu_data);
            //动态创建路由
            buildRouter();
            //设置已经加载过的标记
            store.commit("setLoadRoute", true);
        });
    }
    next();
})

export default router;

此时点击菜单就不会重复加载了。

举报

相关推荐

0 条评论