什么是vue动态路由(Vue 动态菜单+动态路由(基于Element UI))
文章目录
使用场景
主要使用Vue3与Element UI ,在项目开发中可能会遇到从后端取得数据 ,到前端去渲染菜单 ,从而实现动态路由与动态菜单 。
一 、动态菜单
1.创建动态菜单组件
代码如下:
<template> <div> <el-menu :unique-opened="true" :default-openeds="openList" :default-active="/index/ + this.$store.state.TabseditableTabsValue" :collapse-transition="true" router class="el-menu-vertical-demo" style="width: 200px;min-height: calc(100vh );"> <el-sub-menu v-for="(menu, i) in menus" :index="i + 1" :key="i"> <template #title> <el-icon> <Avatar /> </el-icon> <span>{{ menu.authname }}</span> </template> <el-menu-item-group> <el-menu-item @click="getpath(item.path, item.authname, item.name, menu.authname ,menu.path)" :index="/index/ + item.path" v-for="(item, index) in menu.children" :key="index"> <el-icon> <ArrowRight /> </el-icon>{{ item.authname }} </el-menu-item> </el-menu-item-group> </el-sub-menu> </el-menu> </div> </template> <style> .el-menu-item-group__title { display: none; } </style> <script> import { ref } from vue import Tabs from @/components/Tabs.vue; export default { name: Aside, created() { this.getrouter(); }, data() { return { openList: [1], menus: , } }, components: { Tabs }, methods: { //登录界面请求网络已经拿到数据存入vuex,取出数据渲染使用; getrouter() { this.menus=this.$store.state.Routers }, //点击子菜单触发事件 getpath(path, authname, name, Menu_title ,Menu_path) { //将面包屑的数据传入vuex ,方便面包屑数据变换 this.$store.state.Breadcrumb_title = Menu_title; this.$store.state.Breadcrumb.title = authname; this.$store.state.Breadcrumb.path = path; this.$store.state.Breadcrumb.name = name; let tabs = this.$store.state.Tabs; const index = tabs.some(item => { if (item.title === authname) { return true; } else { return false; } }) if (index === false) { //添加Tab标签页(将数据放入vuex存起来) let tab = { title: authname, name: name, path: path, }; this.$store.state.Tabs.push(tab); this.$store.state.TabseditableTabsValue = name; } else { this.$store.state.TabseditableTabsValue = name; } this.$router.replace({path: "/index/"+path}) }, }, } </script>二 、动态面包屑
1.创建面包屑组件
代码如下:
<style> .el-breadcrumb__item{ cursor: pointer; } .el-breadcrumb__item .el-breadcrumb__inner{ cursor: pointer; } </style> <template> <el-breadcrumb style="transform: translate(-12%,-50%);margin-left: 10.7%;padding: 10px;"> <el-breadcrumb-item>首页</el-breadcrumb-item> <el-breadcrumb-item >{{this.$store.state.Breadcrumb_title}}</el-breadcrumb-item> <el-breadcrumb-item replace :to="{path:Breadcrumb.path}" >{{this.$store.state.Breadcrumb.title}}</el-breadcrumb-item> </el-breadcrumb> </template> <script> export default { name: Breadcrumb, created(){ }, components: { }, data() { return { Breadcrumb:this.$store.state.Breadcrumb,//从vuex中拿到面包屑数据并渲染 } }, methods:{ }, } </script>三 、动态标签页
1.创建标签页组件
代码如下:
<template> <el-tabs v-model="this.$store.state.TabseditableTabsValue" type="card" @tab-click="tabClick" closable @tab-remove="removeTab"> <el-tab-pane v-for="(item, index) in editableTabs" :key="index" :label="item.title" :name="item.name"></el-tab-pane> </el-tabs> </template> <script> import store from @/store/index.js; import router from @/router/index.js; export default { name: Tabs, data() { return { editableTabs: store.state.Tabs,//从vuex获取Tabs的数据 。 tabIndex: 2 } }, methods: { //标签页被点击 ,则换面包屑数据 。 tabClick(tab,event) { store.state.Breadcrumb.title=tab.props.label; store.state.Breadcrumb.path=/index/+tab.props.name; store.state.Breadcrumb.name=tab.props.name; router.replace({ path:/index/+tab.props.name }) }, //删除标签页 ,则选中前一个标签页 ,并激活其对应的路由页面 。 removeTab(targetName) { if (targetName == Home) { return } store.commit(delTabRouter, targetName)//在vuex找到方法delTabRouter ,删除标签 。 if (store.state.TabseditableTabsValue == targetName) { // 设置当前激活的路由 if (this.editableTabs && this.editableTabs.length >= 1) { store.state.Breadcrumb.title=this.editableTabs[this.editableTabs.length - 1].title; store.state.Breadcrumb.path=/index/+this.editableTabs[this.editableTabs.length - 1].name; store.state.Breadcrumb.name=this.editableTabs[this.editableTabs.length - 1].name; store.commit(setActiveIndex, this.editableTabs[this.editableTabs.length - 1].name) router.replace({ path: this.editableTabs[this.editableTabs.length - 1].path }) } else { router.replace({ path: /index/Home }) store.state.TabseditableTabsValue = Home; store.commit(setTabRouter, { path: /Home, name: Home, title: 员工信息表 }) } } }, }, } </script>四 、动态路由
1.router
index.js代码如下:
import { createRouter, createWebHistory } from vue-router import store from @/store; const routes = [//初始静态路由 { path: /, name: login, component: () => import(@/views/Login.vue), }, { path: /index, name: Homepage, component: () => import(@/views/Homepage.vue), redirect: /index/Home, children: [{ path: Home, name: Home, component: () => import(@/views/Home.vue), }] }, ] const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes }) var tag = true;//设置全局变量 //路由拦截 router.beforeEach(async (to, form, next) => { //第一次登录时 ,全局变量为true执行 ,第二次刷新 ,再次执行 if (tag) { tag = false; if (to.name === login) { next() } else { let Routers = store.state.Routers; addRoutes(Routers); next(to.path); } } else { next() } }) //添加路由的方法 export function addRoutes(res) { res.forEach((Router, index) => { router.addRoute({ path: Router.path, name: Router.name, component: () => import(@/views/ + Router.name + .vue), }) let childrens = Router.children; if (childrens != undefined) { for (let i = 0; i < childrens.length; i++) { if (childrens[i] != undefined) { router.addRoute(Homepage, { path: childrens[i].path, name: childrens[i].name, component: () => import(@/views/ + childrens[i].name + .vue) }) } } } }) } export default router2.store
index.js代码如下:
import { createStore } from vuex; import router from @/router; export default createStore({ state: { Routers: ,//登录获取的全部路由 setAsyncRoutestMark: false, TabseditableTabsValue: Home,//当前选中Tab的名字 Breadcrumb_title: 员工管理,//菜单栏标签 //全部标签 Tabs: [ { title: 员工信息表, name: Home, path: /index/Home, } ], //选中的标签 Breadcrumb: { title: 员工信息表, name: Home, path: /index/Home } }, getters: { getTabs: state => { return state.Tabs; }, getRouters: state => { return state.Routers; } }, mutations: { //添加tabs路由 setTabRouter(state, data) { state.Tabs.push(data) }, // 删除tabs路由 delTabRouter(state, data) { let index = 0; for (let option of state.Tabs) { if (option.path == data) { break } index++ } state.Tabs.splice(index, 1); // 删完路由后也要保存到session中 // sessionStorage.setItem(Tabs, JSON.stringify(state.Tabs)) }, // 设置当前激活的tabs setActiveIndex(state, index) { state.TabseditableTabsValue = index state.Breadcrumb.name = index; }, }, actions: { }, modules: { } })总结思路
1. 路由守卫判定当初次登录时 ,后端返回路由数据,处理完数据放进vuex存起来 。
2.(1)菜单组件去获取vuex的路由数据 ,进行处理形成自己需要的菜单数据并进行渲染 。
(2)标签页组件去vuex获取Tabs数据 ,进行渲染 。
(3) 面包屑直接从vuex里获取数据,进行渲染 。
3. 操作(1)当子菜单栏被点击时 ,在vuex(即store)里面添加Tab数据 ,同时标签页 、面包屑实时渲染 。
操作(2)当标签页被删除时 ,在vuex里删除其数据 ,同时选中上一次点击的子菜单栏和标签页 ,面包屑也跟着变化
操作(3) 切换标签 ,动态菜单跟着切换选中
4. 当路由守卫判定不为初次登录时 ,则被认为是在刷新 ,则从sessionStorage缓存中找到数据赋值给store ,重新渲染路由 ,使页面不为空白
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!