[VUE学习]权限管理系统前端vue实现9-动态路由,动态标签页,动态面包屑

1.动态路由

        1.因为我们左侧权限菜单是根据不同用户显示不一样的 所以我们需要使用动态路由 来动态生成右侧路由信息

                在总体布局页面添加router

  • <router-view> 是 Vue Router 提供的组件,用于动态展示匹配到的路由组件内容。
  • 通过在合适的位置放置 <router-view>,你可以根据路由路径动态地渲染对应的组件内容。

         2.router里面需要添加children 

                    因为我们是多级页面 之后动态路由也是多级的 如果这里不提前写children 之后动态生成的时候找不到Children

         3.做动态路由是否生成判断 尽量减少生成次数

          1.在store里面添加全局状态

        4.permission.js

router.beforeEach((to,from,next)=>{
    const whiteList=['/login'] // 白名单
    let token=store.getters.GET_TOKEN;
    let hasRoutes = store.state.hasRoutes;
    let menuList = store.getters.GET_MENULIST
    if(token){
        if(!hasRoutes){
            bindRoute(menuList);
            store.commit("SER_ROUTES_STATE",true)
//注意这一行代码 在这一篇文章 详细解释了 如不过写会刷新白屏
            next({ ...to, replace: true })
        }else{
            next();
        }

    }else{
        if(whiteList.includes(to.path)){
            next();
        }else{
            next("/login");
        }
    }
})
const bindRoute=(menuList)=>{
    let newRoutes = router.options.routes;
    menuList.forEach(menu=>{
        if(menu.children){
            menu.children.forEach(m=>{
                let route = menuToRoute(m,menu.name)
                if(route){
                    newRoutes[0].children.push(route);
                }
            })
        }
    })
    //重新添加到路由
    newRoutes.forEach(route=>{
        router.addRoute(route)
    })
}
const menuToRoute=(menu,parentName)=>{
    if(!menu.component){
        return null;
    }else{
        let route={
            name:menu.name,
            path:menu.path,
            meta:{
                parentName:parentName
            }
        }
        route.component=()=>import('@/views/'+menu.component+'.vue')
        return route
    }
}

        1.menuList是我们在登录时候得到的 树形结构 表结构

         2.menuToRounte是动态生成路由  我们传入menu和父级名字(因为父级名字之后会用到)

             生成route对象 包括 name  path  和父级名字 

             component对应着目录结构

          3.生成之后 然后把他们添加到路由里面

       

  1. bindRoute 函数用于将菜单列表转换为路由配置,并添加到路由实例中。它遍历菜单列表,并根据每个菜单项生成对应的路由配置,然后将这些路由配置添加到 newRoutes 数组中。最后,通过 router.addRoute 方法将所有路由配置添加到路由实例中。

  2. menuToRoute 函数用于将菜单项转换为路由配置。如果菜单项没有指定组件,则返回 null;否则,生成一个包含菜单名、路径和父菜单名的路由配置对象,并设置组件为异步加载形式。

2.动态标签页

        

 1.store里面添加标签页数组 一个是当前标签页 一个是全部打开的

         

    state: {
        hasRoutes: false,
        editableTabsValue: '/index',
        editableTabs: [
            {
                title: '首页',
                name: '/index'
            }
        ]
    },

       

        ADD_TABS: (state, tab) => {
            if (state.editableTabs.findIndex(e => e.name == tab.path) === -1) {
                state.editableTabs.push({
                    title: tab.name,
                    name: tab.path
                })
            }
            state.editableTabsValue = tab.path
        },
        RESET_TABS: (state) => {
            state.editableTabsValue = '/index',
                state.editableTabs = [
                    {
                        title: '首页',
                        name: '/index'
                    }
                ]
        },

安全退出时候 调用RESET_TABS这个方法 清空

  if(result.data.code===200){
    store.commit("SER_ROUTES_STATE",false)
    store.commit("RESET_TABS")
    store.dispatch('logout')
  }

在menuIndex里面添加 click点击事件

2.tabIndex具体实现

        1.关联store里面数据

                涉及到路由 使用useRouter

const router = useRouter();
const editableTabsValue = ref(store.state.editableTabsValue)
const editableTabs = ref(store.state.editableTabs)

                 因为我们关联的是store里面的数据 所以当我们store里面数据发生更改之后 页面并没有发生改变 所以我们需要对数据进行监听 当发生更改之后 重新赋值

<template>

<!--  选中-->
  <el-tabs
      v-model="editableTabsValue"
      type="card"
      class="demo-tabs"
      closable
      @tab-remove="removeTab"
      @tab-click="clickTab"
  >
<!-- 所有tab-->
    <el-tab-pane
        v-for="item in editableTabs"
        :key="item.name"
        :label="item.title"
        :name="item.name"
    >
      {{ item.content }}
    </el-tab-pane>
  </el-tabs>
</template>
<script  setup>
import {ref, watch} from 'vue'
import store from '@/store'
import {useRouter} from "vue-router";

const router = useRouter();

const editableTabsValue = ref(store.state.editableTabsValue)
const editableTabs = ref(store.state.editableTabs)


const removeTab = (targetName) => {
  const tabs = editableTabs.value
  let activeName = editableTabsValue.value

  // 这里是Path  使得无法删除首页
  if(targetName==='/index'){
    return
  }

  if (activeName === targetName) {
    tabs.forEach((tab, index) => {
      if (tab.name === targetName) {
        const nextTab = tabs[index + 1] || tabs[index - 1]
        if (nextTab) {
          activeName = nextTab.name
        }
      }
    })
  }

  editableTabsValue.value = activeName
  editableTabs.value = tabs.filter((tab) => tab.name !== targetName)

  store.state.editableTabsValue = editableTabsValue.value
  store.state.editableTabs=editableTabs.value

  // 这个获取的是path
  router.push({path:activeName})
}

const refreshTabs =()=>{
  editableTabsValue.value=store.state.editableTabsValue;
  editableTabs.value=store.state.editableTabs;
}

// 可以拿到标签名称 可以根据Name  也可以根据path
const clickTab =(target)=>{
  router.push({name:target.props.label})
}

// 监听变化
watch(store.state,()=>{
  refreshTabs();
},{deep:true,immediate:true})
// 深度监听

</script>
<style>
.demo-tabs > .el-tabs__content {
  padding: 32px;
  color: #6b778c;
  font-size: 32px;
  font-weight: 600;
}

.el-main{
  padding:0px;
}


.el-tabs--card>.el-tabs__header .el-tabs__item.is-active{
  background-color: lightgray;
}

.el-tabs{
  height:45px
}
</style>

3.动态面包屑实现

        面包屑

         这里就使用到了我们前面提到的parentName 

        三个if  

        如果是父级名字 并且index大于一 显示并且加 /  系统管理/

        如果是最后一个直接显示      角色管理

<template>
  <el-icon><HomeFilled /></el-icon>
    <el-breadcrumb separator="/">

      <el-breadcrumb-item v-for="(item,index) in breadcrumbList" :key="index">
        <span class="root" v-if="parentName && index>0">{{parentName}}&nbsp;&nbsp;/&nbsp;&nbsp;</span>
        <span class="leaf" v-if="index==breadcrumbList.length-1">{{item.name}}</span>
        <span class="root" v-else>{{item.name}}</span>
      </el-breadcrumb-item>

    </el-breadcrumb>
</template>

<script setup>
import { ref,watch } from 'vue'
import {HomeFilled} from '@element-plus/icons-vue'
import {useRoute} from 'vue-router'
import store from "@/store";

const route=useRoute();
const breadcrumbList=ref([]);
const parentName=ref("")

const initBreadcrumbList=()=>{
  breadcrumbList.value=route.matched;
  parentName.value=route.meta.parentName;
}

watch(route,()=>{
  initBreadcrumbList();
},{deep:true,immediate:true})


</script>

<style lang="scss" scoped>
.leaf{
  cursor:text;
}
.root{
  color:#666;
  font-weight:600;
}
</style>

4.路由与导航动态绑定实现

             为了防止有人不点击 直接输入Url跳转  首先App.vue里面监听 然后添加标签页数据  此时标签页可以动态变化

import { ref ,watch} from 'vue'
import { useRoute,useRouter } from 'vue-router'
const route=useRoute();
const router=useRouter();
const whitePath=['/login','/index','/']


watch(route,(to,from)=>{
  console.log("to"+to.name)
  console.log(to.path)

  if (whitePath.indexOf(to.path)===-1) {
    console.log("to.path="+to.path)
    let obj = {
      name: to.name,
      path: to.path
    }

    store.commit("ADD_TABS", obj)
  }

},{deep:true,immediate:true})

        修改menu使得菜单栏也可以动态变化

 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot 和 Vue 结合使用,可以通过 Element UI 来实现动态路由。 具体步骤如下: 1. 在 Spring Boot 中,定义一个 API 接口,用于返回动态路由的配置信息,例如菜单列表、权限信息等。 2. 在 Vue 中,使用 axios 等工具调用该 API 接口获取动态路由的配置信息。 3. 在 Vue 中,使用 vue-router 来实现路由功能。在路由配置中,使用获取到的动态路由信息来动态生成路由。例如,使用菜单列表来生成菜单路由,使用权限信息来控制路由的访问权限等。 4. 在 Vue 中,结合 Element UI 的组件,可以实现一些常见的路由功能,例如面包屑导航、菜单栏等。 综上所述,通过 Spring Boot、Vue 和 Element UI 的结合,可以实现动态路由功能,从而实现更加灵活、可扩展的前端面管理。 ### 回答2: Spring Boot是一个开发框架,Vue是一个前端框架,Element UI是一个UI组件库,如何实现动态路由呢? 首先,在Spring Boot后端,需要定义一个接口来获取动态路由的数据。可以使用一个数据库表来存储路由信息,如路由路径、组件名称、图标等。然后,通过编写一个控制器类,来处理获取动态路由数据的请求。在该控制器类中,可以调用相应的服务类或数据访问层来获取路由数据,并返回给前端。 接下来,在Vue前端项目中,可以使用Vue Router来实现动态路由。可以在项目的入口文件(如main.js)中,通过发送请求获取动态路由数据。可以使用axios等库来发送请求,获取后端返回的动态路由数据。获取到数据后,可以通过遍历的方式,动态地把路由配置项添加到Vue Router中。 同时,在项目中引入Element UI组件库,可以使用其中的菜单、导航等组件,来展示动态路由。可以根据获取的动态路由数据,来生成菜单和导航栏的数据,并将其展示在面中。 为了实现动态路由的跳转,可以使用Vue Router中的路由守卫(如beforeEach),在路由跳转之前判断是否有权限访问该路由。可以根据当前用户的权限信息,来判断是否有权限访问该路由。如果没有权限,则可以跳转到其他面或者显示相应的提示信息。 总结来说,通过在Spring Boot后端定义接口获取动态路由数据,并在Vue前端项目中将其配置到Vue Router中,配合使用Element UI的菜单、导航组件,就可以实现Spring Boot、Vue和Element UI的动态路由。 ### 回答3: 要实现动态路由,我们可以结合使用Spring Boot、Vue和Element UI。 首先,在Spring Boot后端,我们需要建立一个API接口,用于获取动态路由的数据。这个接口可以返回一个JSON对象,包含了多个路由对象的信息,如路由名称、路径、组件等。 接下来,在Vue前端,我们可以使用Element UI的导航菜单组件来实现动态路由。首先,我们需要在Vue项目中安装Element UI,并引入导航菜单组件。然后,在主面组件中,我们可以通过调用后端的API接口获取动态路由数据,然后根据返回的数据动态生成导航菜单。可以使用Vue Router来管理路由,并使用 `<router-view>` 标签来展示对应的面组件。 在生成导航菜单时,我们可以使用递归组件来实现无限嵌套的导航菜单结构。每个导航菜单项可以绑定点击事件,当用户点击菜单项时,可以通过Vue Router进行路由跳转,展示对应的面组件。 为了保证路由权限控制,我们可以在后端API接口中加入用户权限验证的逻辑。在前端,我们可以根据用户的角色或权限信息动态生成导航菜单,只展示用户有权限访问的路由。 总结来说,使用Spring Boot提供API接口获取动态路由数据,然后在Vue前端使用Element UI的导航菜单组件构建动态路由。通过递归组件生成无限嵌套的导航菜单,并通过Vue Router实现路由跳转。同时,可以结合用户权限信息进行路由权限控制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值