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

1、前端代码实现

1.App.vue

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




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(侧边栏)




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> listUserMenus() {
        return ResultVO.ok(menuService.listUserMenus());
    }
}

2.Service层

public interface MenuService extends IService {

	List 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 implements MenuService {

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


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

	private List convertUserMenuList(List catalogList, Map> childrenMap) {
		return catalogList.stream().map(item -> {
			UserMenuDTO userMenuDTO = new UserMenuDTO();
			List list = new ArrayList<>();
			List 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 children;

}

6.mybatis.xml

 

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从后端取数据,实现动态路由_第1张图片

 按照上面要求即可实现

你可能感兴趣的:(vue.js,前端,javascript)