Vue从后端取数据,实现动态路由

这篇具有很好参考价值的文章主要介绍了Vue从后端取数据,实现动态路由。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、前端代码实现

1.App.vue

        将获取菜单的方法放在全局中,以便每次刷新页面时,能够加载出。this.$store.state.userInfo是登入后存放在Vuex的用户信息

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
import { generaMenu } from '@/assets/js/menu'
export default {
  created() {
    if (this.$store.state.userInfo != null) {
      generaMenu()
    }
  }
}
</script>

2.menu.js(@/assets/js路径下)

import Layout from '@/layout/index.vue'
import router from '@/router'
import store from '@/store'
import axios from 'axios'
import Vue from 'vue'

export function generaMenu() {
  axios.get('/api/admin/user/menus').then(({ data }) => {
    if (data.flag) {
      let userMenus = data.data;
      userMenus.forEach((item) => {
        if (item.icon != null) {
          item.icon = 'iconfont ' + item.icon
        }
        if (item.component == 'Layout') {
          item.component = Layout
        }
        if (item.children && item.children.length > 0) {
          item.children.forEach((route) => {
            route.icon = 'iconfont ' + route.icon;
            route.component = loadView(route.component)
          })
        }
      })
      store.commit('saveUserMenus', userMenus);
      userMenus.forEach((item) => {
        router.addRoute(item)
      })
    } else {
      Vue.prototype.$message.error(data.message);
      router.push({ path: '/login' })
    }
  })
}

export const loadView = (view) => {
  return (resolve) => require([`@/views${view}`], resolve)
}

3.SideBar.vue(侧边栏)

<template>
  <div>
    <el-menu
      class="side-nav-bar"
      router
      :collapse="this.$store.state.collapse"
      :default-active="this.$route.path"
      background-color="#304156"
      text-color="#BFCBD9"
      active-text-color="#409EFF">
      <template v-for="route of this.$store.state.userMenus">
        <template v-if="route.name && route.children && !route.hidden">
          <el-submenu :key="route.path" :index="route.path">
            <template slot="title">
              <i :class="route.icon" />
              <span>{{ route.name }}</span>
            </template>
            <template v-for="(item, index) of route.children">
              <el-menu-item v-if="!item.hidden" :key="index" :index="item.path">
                <i :class="item.icon" />
                <span slot="title">{{ item.name }}</span>
              </el-menu-item>
            </template>
          </el-submenu>
        </template>
        <template v-else-if="!route.hidden">
          <el-menu-item :index="route.path" :key="route.path">
            <i :class="route.children[0].icon" />
            <span slot="title">{{ route.children[0].name }}</span>
          </el-menu-item>
        </template>
      </template>
    </el-menu>
  </div>
</template>

<style scoped>
.side-nav-bar:not(.el-menu--collapse) {
  width: 210px;
}
.side-nav-bar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  overflow-x: hidden;
  overflow-y: auto;
}
.side-nav-bar i {
  margin-right: 1rem;
}
*::-webkit-scrollbar {
  width: 0.5rem;
  height: 1px;
}
*::-webkit-scrollbar-thumb {
  border-radius: 0.5rem;
  background-color: rgba(144, 147, 153, 0.3);
}
</style>

2、后端代码(SpringBoot)

1.Controller层

package com.pzg.chat.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.api.R;
import com.pzg.chat.model.dto.MenuDTO;
import com.pzg.chat.model.dto.UserMenuDTO;
import com.pzg.chat.model.vo.ConditionVO;
import com.pzg.chat.model.vo.ResultVO;
import com.pzg.chat.service.MenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;

/**
 * (SysMenu)表控制层
 *
 * @author makejava
 * @since 2024-01-17 14:38:59
 */
@Api(tags = "菜单模块")
@RestController
public class MenuController {

    @Resource
    private MenuService menuService;


    @ApiOperation(value = "查看当前用户菜单")
    @GetMapping("/admin/user/menus")
    public ResultVO<List<UserMenuDTO>> listUserMenus() {
        return ResultVO.ok(menuService.listUserMenus());
    }
}

2.Service层

public interface MenuService extends IService<Menu> {

	List<UserMenuDTO> listUserMenus();
}

3.ServiceImpl层

package com.pzg.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pzg.chat.constant.CommonConstant;
import com.pzg.chat.entity.Menu;
import com.pzg.chat.mapper.MenuMapper;
import com.pzg.chat.model.dto.MenuDTO;
import com.pzg.chat.model.dto.UserMenuDTO;
import com.pzg.chat.model.vo.ConditionVO;
import com.pzg.chat.service.MenuService;
import com.pzg.chat.utils.BeanCopy;
import com.pzg.chat.utils.UserUtil;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.pzg.chat.constant.CommonConstant.COMPONENT;
import static com.pzg.chat.constant.CommonConstant.TRUE;


@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

	@Override
	public List<UserMenuDTO> listUserMenus() {
		Integer id = UserUtil.getUserDetailsDTO().getId();
		List<Menu> menus = this.baseMapper.listMenusByUserInfoId(id);
		List<Menu> catalogs = listCatalogs(menus);
		Map<Integer, List<Menu>> childrenMap = getMenuMap(menus);
		List<UserMenuDTO> userMenuDTOS = convertUserMenuList(catalogs, childrenMap);
		return userMenuDTOS;
	}


	private List<Menu> listCatalogs(List<Menu> menus) {
		return menus.stream()
				.filter(item -> Objects.isNull(item.getParentId()))
				.sorted(Comparator.comparing(Menu::getOrderNum))
				.collect(Collectors.toList());
	}

	private List<UserMenuDTO> convertUserMenuList(List<Menu> catalogList, Map<Integer, List<Menu>> childrenMap) {
		return catalogList.stream().map(item -> {
			UserMenuDTO userMenuDTO = new UserMenuDTO();
			List<UserMenuDTO> list = new ArrayList<>();
			List<Menu> children = childrenMap.get(item.getId());
			if (CollectionUtils.isNotEmpty(children)) {
				userMenuDTO = BeanCopy.singleCopy(item, UserMenuDTO.class);
				list = children.stream()
						.sorted(Comparator.comparing(Menu::getOrderNum))
						.map(menu -> {
							UserMenuDTO dto = BeanCopy.singleCopy(menu, UserMenuDTO.class);
							dto.setHidden(menu.getIsHidden().equals(TRUE));
							return dto;
						})
						.collect(Collectors.toList());
			} else {
				userMenuDTO.setPath(item.getPath());
				userMenuDTO.setComponent(COMPONENT);
				list.add(UserMenuDTO.builder()
						.path("")
						.name(item.getName())
						.icon(item.getIcon())
						.component(item.getComponent())
						.build());
			}
			userMenuDTO.setHidden(item.getIsHidden().equals(TRUE));
			userMenuDTO.setChildren(list);
			return userMenuDTO;
		}).collect(Collectors.toList());
	}

}

4.Menu类

package com.pzg.chat.entity;

import java.time.LocalDateTime;
import java.util.Date;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * (SysMenu)表实体类
 *
 * @author makejava
 * @since 2024-01-17 14:38:59
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@TableName("sys_menu")
public class Menu {
    //主键
    private Integer id;
    //菜单名
    private String name;
    //菜单路径
    private String path;
    //组件
    private String component;
    //菜单icon
    private String icon;
    //创建时间
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    //更新时间
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    //排序
    private Integer orderNum;
    //父id
    private Integer parentId;
    //是否隐藏  0否1是
    private Integer isHidden;


}

5.UserMenuDTO 

package com.pzg.chat.model.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserMenuDTO {

    private String name;

    private String path;

    private String component;

    private String icon;

    private Boolean hidden;

    private List<UserMenuDTO> children;

}

6.mybatis.xml

 <select id="listMenusByUserInfoId" resultType="com.pzg.chat.entity.Menu">
        SELECT DISTINCT m.id,
                        name,
                        path,
                        component,
                        icon,
                        is_hidden,
                        parent_id,
                        order_num
        FROM user_role ur
                 JOIN sys_role_menu rm ON ur.role_id = rm.role_id
                 JOIN sys_menu m ON rm.menu_id = m.id
        WHERE user_info_id = #{userInfoId}
    </select>

3、数据库表结构

1.表sys_menu

CREATE TABLE `sys_menu` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名',
  `path` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单路径',
  `component` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '组件',
  `icon` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单icon',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `order_num` tinyint(1) NOT NULL COMMENT '排序',
  `parent_id` int DEFAULT NULL COMMENT '父id',
  `is_hidden` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否隐藏  0否1是',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=229 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC

2.表sys_role

CREATE TABLE `sys_role` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '角色id',
  `role_name` varchar(120) NOT NULL COMMENT '角色名',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `updateTime` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

3.表sys_role_menu

CREATE TABLE `sys_role_menu` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `role_id` int DEFAULT NULL COMMENT '角色id',
  `menu_id` int DEFAULT NULL COMMENT '菜单id',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3060 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC

4. 表sys_user_info

CREATE TABLE `sys_user_info` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '用户详情id',
  `nick_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '昵称',
  `username` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '账号',
  `gender` int DEFAULT NULL COMMENT '性别',
  `avatar` varchar(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '头像',
  `address` varchar(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '地址',
  `disable` int DEFAULT NULL COMMENT '是否禁用(0禁用,1不禁用)',
  `date_birth` datetime DEFAULT NULL COMMENT '出生日期',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

 4、效果

Vue从后端取数据,实现动态路由,vue.js,前端,javascript

 按照上面要求即可实现文章来源地址https://www.toymoban.com/news/detail-807490.html

到了这里,关于Vue从后端取数据,实现动态路由的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3 - 详细实现下载从服务端返回的文件流 Blob 对象教程,前端下载后端接口返回的文件流并自动保存到本地,支持任何格式的文件下载(从后端拿到二进制文件流 Blob 对象,前端实现点击下载功能)

    调用服务端(后端)接口拿到文件流,通过前端下载并保存到本地。 本文 实现了在 vue3 项目中,通过后端接口返回的二进制文件流 Blob 对象,在前端进行点击下载并保存到用户本地,任何格式的文件都可以轻松下载, 保证您直接复制代码,改个请求地址就可以使用了, 如下

    2024年02月04日
    浏览(211)
  • 路由原理及vue实现动态路由

    在前端开发中,路由通常用于实现 SPA 应用程序,即在一个页面中切换不同的内容或页面,而不需要重新加载整个页面。路由的实现原理是通过监听 URL 的变化,然后根据不同的 URL 加载不同的内容或页面。 在前端框架中,例如 Vue,路由通常是通过路由库来实现的。路由库提

    2024年02月06日
    浏览(44)
  • vue 实现动态路由

    vue-router对象中的 addRoutes ,用它来动态添加路由配置 格式: 举个例子: 我是以 vue-admin-template 为例,做如下演示: 在router/index.js中的路由配置中 只保留静态路由(因为我们要动态的添加)) 在permission.js中引入,并使用addRoutes动态添加 这个是 router 下的 index.js中定义的 静态

    2024年02月01日
    浏览(40)
  • Vue实现动态路由

    目录 前言 一、项目介绍 1.开发环境 2.功能 3.项目运行截图   二、实现 1.动态路由如何实现 2.项目目录介绍 3.核心代码 4.坑和知识点 小结 最近在学权限相关的管理项目,前端用到了动态路由,就是根据用户角色显示不同的菜单,动态添加路由。说着好像很简单,但看了很多

    2024年02月06日
    浏览(35)
  • Vue.js与后端交互:构建动态数据应用的完美指南

    「作者主页」 :雪碧有白泡泡 「个人网站」 :雪碧的个人网站 「推荐专栏」 : ★ java一站式服务 ★ ★ 前端炫酷代码分享 ★ ★ uniapp-从构建到提升 ★ ★ 从0到英雄,vue成神之路 ★ ★ 解决算法,一个专栏就够了 ★ ★ 架构咱们从0说 ★ ★ 数据流通的精妙之道★ Vue.js是一

    2024年02月17日
    浏览(39)
  • [VUE学习]权限管理系统前端vue实现9-动态路由,动态标签页,动态面包屑

                    在总体布局页面添加router router-view 是 Vue Router 提供的组件,用于动态展示匹配到的路由组件内容。 通过在合适的位置放置 router-view ,你可以根据路由路径动态地渲染对应的组件内容。                     因为我们是多级页面 之后动态路由也是多级的 如

    2024年02月13日
    浏览(46)
  • Vue实现动态路由【记录学习的快乐】

    1、什么是动态路由? 2、动态路由的好处 3、动态路由如何实现 1、什么是动态路由? 动态路由,动态即不是写死的,是可变的。我们可以根据自己不同的需求加载不同的路由,做到不同的实现及页面的渲染。动态的路由存储可分为两种,一种是将路由存储到前端。另一种则

    2024年02月07日
    浏览(33)
  • Vue.js:Vue-Router动态路由从服务器接口获取路由数据

    文档 https://v3.router.vuejs.org/zh/installation.html 版本号 有几种方式实现动态路由: 前端配置 完整路由 ,通过接口返回的数据判断是否可显示,是否可访问 前端配置 部分路由 ,由后端接口返回的数据生成新路由 抛开路由的思维,是否能直接通过 url查询参数 或者是 动态路径参数

    2024年02月08日
    浏览(56)
  • vue实现动态路由添加(简单无废话版本)

    最近练习vue的项目,有关于后台管理系统的动态添加路由部分,根据思路实现了基本的功能,在这里记录一下,等后面学习后在进行优化。 这里只是记录我个人最后实现的思路,本人由于是初学者,可能思路和代码有不正确地方,还求多见谅。也请能不吝赐教,一同进步。 我

    2023年04月08日
    浏览(36)
  • Vue如何实现权限管理(动态路由addRoutes)

    目录 引言 推荐B站视频 一、权限管理 二、控制权限 接口权限 路由权限控制 方法一 方法二 菜单权限 方法一 方法二 按钮权限 方法一 方法二 项目中会遇到权限管理,来让特定用户有特定权限的场景,那么怎么做这个权限管理,以及有多少办法呢,下面给大家絮叨 vue权限管

    2023年04月25日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包