VUE:SpringBoot + Vue 菜单管理

(十)VUE侧边菜单栏导航--基于SpringBoot+MySQL+Vue+ElementUI+Mybatis前后端分离面向小白管理系统搭建 VUE侧边菜单栏导航设计(1)理解并逐步掌握VUE组件的含义;(2)深入理解VUE单页面应用;(3)初步掌握VUE路由的概念和使用方法。 阅读详情

简单的记录下菜单前后端实现,比较基础,仅供参考
vue请求需要根据情况自行封装,代码中的请求需要自行实现

效果

在这里插入图片描述

数据库结构

CREATE TABLE `menus` (
	`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键,菜单id',
	`name` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '菜单名称' COLLATE 'utf8_general_ci',
	`icon` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '菜单图标' COLLATE 'utf8_general_ci',
	`route` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '菜单路由' COLLATE 'utf8_general_ci',
	`superior_menu` INT(11) NOT NULL DEFAULT '0' COMMENT '上级菜单',
	`sort_number` INT(11) NOT NULL DEFAULT '0' COMMENT '排序',
	`show_level` INT(11) NOT NULL DEFAULT '0' COMMENT '权限级别',
	`create_time` TIMESTAMP NULL DEFAULT '1970-01-01 08:00:01' COMMENT '创建时间',
	`update_time` TIMESTAMP NULL DEFAULT '1970-01-01 08:00:01' ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
	`status` INT(11) NOT NULL DEFAULT '0' COMMENT '是否启用,0:启用,1禁用',
	PRIMARY KEY (`id`) USING BTREE,
	UNIQUE INDEX `u_key_s_n` (`superior_menu`, `name`) USING BTREE,
	UNIQUE INDEX `u_key_s_s` (`superior_menu`, `sort_number`) USING BTREE
)
COMMENT='侧边栏菜单'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

Java对象

package com.xiaobai.test;

import java.util.Date;
import java.util.List;

public class Menu {
    private Integer id;

    private String name;

    private String icon;

    private String route;

    private Integer superior_menu;

    private Integer sort_number;

    private Integer show_level;

    private Date create_time;

    private Date update_time;

    private Integer status;

    private List<Menu> subMenus;

    public Menu() {

    }

    public Menu(Integer id, String name, String icon, String route, Integer superior_menu, Integer sort_number, Integer show_level, Integer status) {
        this.id = id;
        this.name = name;
        this.icon = icon;
        this.route = route;
        this.superior_menu = superior_menu;
        this.sort_number = sort_number;
        this.show_level = show_level;
        this.status = status;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    public String getRoute() {
        return route;
    }

    public void setRoute(String route) {
        this.route = route;
    }

    public Integer getSuperior_menu() {
        return superior_menu;
    }

    public void setSuperior_menu(Integer superior_menu) {
        this.superior_menu = superior_menu;
    }

    public Integer getSort_number() {
        return sort_number;
    }

    public void setSort_number(Integer sort_number) {
        this.sort_number = sort_number;
    }

    public Integer getShow_level() {
        return show_level;
    }

    public void setShow_level(Integer show_level) {
        this.show_level = show_level;
    }

    public Date getCreate_time() {
        return create_time;
    }

    public void setCreate_time(Date create_time) {
        this.create_time = create_time;
    }

    public Date getUpdate_time() {
        return update_time;
    }

    public void setUpdate_time(Date update_time) {
        this.update_time = update_time;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public List<Menu> getSubMenus() {
        return subMenus;
    }

    public void setSubMenus(List<Menu> subMenus) {
        this.subMenus = subMenus;
    }
}

Controller

@Controller
@RequestMapping("/menu")
public class MenuController {

    @Autowired
    MenuService menuService;

    @RequestMapping("/queryMenus")
    @ResponseBody
    public ResponseEntity queryMenus(@RequestParam(value = "id", required = false) Integer id,
                                     @RequestParam(value = "level", required = false, defaultValue = "0") Integer level,
                                     @RequestParam(value = "status", required = false) Integer status,
                                     @RequestParam(value = "querySubMenus", required = false, defaultValue = "true") Boolean querySubMenus) {
        // 如果为系统管理员,不受菜单禁用限制,枚举类型,请根据情况自行定义,如无特殊要求注释掉该条件判断
        if (level == LevelType.TYPE.SYSTEM.getCode()) {
            status = null;
        }

        List<Menu> menus = menuService.queryMenus(null, id, level, status);
        menus.sort(Comparator.comparingInt(Menu::getSort_number));
        // 判断是否查询子菜单
        if (querySubMenus != null && querySubMenus == true) for (Menu menu : menus) {
            List<Menu> subMenus = querySubMenus(menu, level, status);
            menu.setSubMenus(subMenus);
        }
        Map<String, Object> response = new HashMap<>();
        response.put("msg", "查询成功");
        response.put("code", 200);
        response.put("data", menus);
        return new ResponseEntity(response, HttpStatus.OK);
    }


    private List<Menu> querySubMenus(Menu menu, Integer level, Integer status) {
        List<Menu> subMenus = menuService.queryMenus(menu, null, level, status);
        if (subMenus.size() > 0) {
            subMenus.sort(Comparator.comparingInt(Menu::getSort_number));
            menu.setSubMenus(subMenus);
            for (Menu subMenu : subMenus) {
                List<Menu> menus = querySubMenus(subMenu, level, status);
                subMenu.setSubMenus(menus);
            }
        }
        return subMenus;
    }


    @RequestMapping("/queryMenuById")
    @ResponseBody
    public ResponseEntity queryMenuById(@RequestParam(value = "id", required = false) Integer id,
                                        @RequestParam(value = "level", required = false, defaultValue = "0") Integer level) {

        Menu menu = menuService.queryMenuById(id);
        Map<String, Object> response = new HashMap<>();
        response.put("msg", "查询成功");
        response.put("code", 200);
        response.put("data", menu);
        return new ResponseEntity(response, HttpStatus.OK);
    }

    @RequestMapping("/addMenu")
    @ResponseBody
    public ResponseEntity addMenu(@RequestParam(value = "name", required = false) String name,
                                  @RequestParam(value = "icon", required = false) String icon,
                                  @RequestParam(value = "route", required = false) String route,
                                  @RequestParam(value = "superior_menu", required = false) Integer superior_menu,
                                  @RequestParam(value = "sort_number", required = false) Integer sort_number,
                                  @RequestParam(value = "level", required = false) Integer level,
                                  @RequestParam(value = "status", required = false) Integer status) {
        // 修改当前菜单状态
        Menu menu = new Menu(null, name, icon, route, superior_menu, sort_number, level, status);
        menuService.insertMenu(menu);

        Map<String, Object> response = new HashMap<>();
        response.put("msg", "添加成功");
        response.put("code", 200);
        return new ResponseEntity(response, HttpStatus.OK);
    }
}

mapper

public interface MenuMapper {
    List<Menu> queryMenus(@Param("menu") Menu menu, @Param("id") Integer id, @Param("level") Integer level, @Param("status") Integer status);

    Integer insertMenu(Menu menu);

    Integer updateMenu(Menu menu);

    Menu queryMenuById(@Param("id") Integer id);
}

service

public interface MenuService {
    List<Menu> queryMenus(Menu menu, Integer id, Integer level, Integer status);

    Integer updateMenu(Menu menu);

    Integer insertMenu(Menu menu);

    Menu queryMenuById(Integer id);
}

serviceImpl

@Service("MenuService")
public class MenuServiceImpl implements MenuService {
    @Resource
    private MenuMapper menuMapper;

    @Override
    public List<Menu> queryMenus(Menu menu, Integer id, Integer level, Integer status) {
        return menuMapper.queryMenus(menu, id, level, status);
    }

    @Override
    public Integer insertMenu(Menu menu) {
        return menuMapper.insertMenu(menu);
    }

    @Override
    public Integer updateMenu(Menu menu) {
        return menuMapper.updateMenu(menu);
    }

    @Override
    public Menu queryMenuById(Integer id) {
        return menuMapper.queryMenuById(id);
    }
}

mybatis.xml

自行修改对应的namespace和resultType等参数

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xxx.MenuMapper">
    <insert id="insertMenu" keyColumn="id" keyProperty="id"
            parameterType="xxx.Menu"
            useGeneratedKeys="true">
        insert into menus(`name`, `icon`, `route`, `superior_menu`, `sort_number`, `show_level`, `create_time`, `update_time`, `status`) values
            (#{name}, #{icon}, #{route}, #{superior_menu}, #{sort_number}, #{show_level}, now(), now(), #{status})
    </insert>

    <select id="queryMenus" resultType="xxx.Menu">
        select `id`, `name`, `icon`, `route`, `superior_menu`,`sort_number`, `show_level`, `status`, `create_time`, `update_time`
        from `menus`
        <where>
            show_level <![CDATA[ <= ]]> #{level}
            <if test="menu!=null and menu.id!=null">
                and `superior_menu`= #{menu.id}
            </if>
            <if test="id != null">
                and `id`= #{id}
            </if>
            <if test="menu==null or menu.superior_menu==null">
                and `superior_menu`= 0
            </if>
            <if test="status!=null">
                and `status`= #{status}
            </if>
        </where>
    </select>

    <select id="queryMenuById" resultType="xxx.Menu">
        select * from menus where id = #{id}
    </select>

    <update id="updateMenu">
        update menus
        <set>
            <if test="name != null">
                `name`=#{name,jdbcType=VARCHAR},
            </if>
            <if test="icon != null">
                icon=#{icon,jdbcType=VARCHAR},
            </if>
            <if test="route != null">
                route=#{route,jdbcType=VARCHAR},
            </if>
            <if test="superior_menu != null">
                superior_menu=#{superior_menu,jdbcType=INTEGER},
            </if>
            <if test="sort_number != null">
                sort_number=#{sort_number,jdbcType=INTEGER},
            </if>
            <if test="show_level != null">
                show_level=#{show_level,jdbcType=INTEGER},
            </if>
            <if test="status != null">
                status=#{status,jdbcType=INTEGER},
            </if>
        </set>
        where id = #{id,jdbcType=INTEGER}
    </update>

</mapper>

VUE前端

<template>
	<div>
		<div class="div-padding">
			<el-row :gutter="10" class="mgt20">
				<el-col>
					<i class="el-icon-menu" style="line-height: 30px; width: 30px; color:blue; font-size: 20px;"></i>
					<span class="span-page-title">菜单管理</span>
				</el-col>
			</el-row>
			<el-row :gutter="10">
				<el-col :span="2">
					<el-button style="width: 90px; line-height: 13px;" type="primary"
						@click="onOpenAddMenuDialogButtonClick()">新增</el-button>
				</el-col>
			</el-row>

			<el-row :gutter="10" class="mgt20">
				<el-col>
					<el-table border :data="menuList" class="table" border row-key="id"
						:tree-props="{children: 'subMenus'}" header-cell-class-name="table-header">
						<el-table-column prop="id" :show-overflow-tooltip="true" label="菜单编号"
							width="100px"></el-table-column>
						<el-table-column prop="name" :show-overflow-tooltip="true" label="菜单名称"></el-table-column>
						<el-table-column prop="icon" :show-overflow-tooltip="true" align="center" label="菜单图标">
							<template slot-scope="scope">
								<i :class="scope.row.icon"></i>
							</template>
						</el-table-column>
						<el-table-column prop="route" :show-overflow-tooltip="true" label="路由"
							width="130px"></el-table-column>
						<el-table-column prop="superior_menu" :show-overflow-tooltip="true" label="父菜单编号" width="90px">
						</el-table-column>
						<el-table-column prop="sort_number" :show-overflow-tooltip="true" label="菜单排序">
						</el-table-column>
						<el-table-column prop="show_level" :show-overflow-tooltip="true" label="显示级别">
						</el-table-column>
						<el-table-column prop="update_time" :show-overflow-tooltip="true" label="更新时间" width="160px">
							<template slot-scope="scope">
								{{$moment(scope.row.update_time).format("YYYY-MM-DD HH:mm:ss")}}
							</template>
						</el-table-column>
						<el-table-column prop="status" :show-overflow-tooltip="true" label="状态">
							<template slot-scope="scope">
								<el-tag type="success" v-if="scope.row.status == 0">已启用</el-tag>
								<el-tag type="danger" v-if="scope.row.status == 1">已禁用</el-tag>
							</template>
						</el-table-column>
						<el-table-column label="操作" width="200px">
							<template slot-scope="scope">
								<el-button v-if="scope.row.status==1" icon="el-icon-check" type="primary" plain
									size="mini" @click="enabledMenu(scope)">
									启用
								</el-button>
								<el-button v-if="scope.row.status==0" icon="el-icon-delete" type="danger" plain
									size="mini" @click="disabledMenu(scope)">
									禁用
								</el-button>
								<el-button icon="el-icon-edit" type="success" plain size="mini"
									@click="onOpenModifyMenuDialogButtonClick(scope)">
									编辑
								</el-button>
							</template>
						</el-table-column>
					</el-table>
				</el-col>
			</el-row>
		</div>

		<!-- ========================================================== 新增、修改对话框  ========================================================== -->
		<el-dialog width="30%" :title="menuDialog.title" :close-on-click-modal="false"
			@close="onCloseMenuDialogButtonClick()" :close-on-press-escape="false" :visible.sync="menuDialog.visible">
			<el-form :rules="rules" ref="ruleForm" :model="menuDialog.ruleForm" label-width="100px"
				class="demo-ruleForm">
				<el-row>
					<el-col :span="24">
						<el-form-item label="菜单名称" prop="name">
							<el-input style="width: 80%;" v-model="menuDialog.ruleForm.name"></el-input>
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item label="菜单图标" prop="icon">
							<el-input style="width: 80%;" v-model="menuDialog.ruleForm.icon"></el-input>
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item label="菜单路由" prop="route">
							<el-input style="width: 80%;" v-model="menuDialog.ruleForm.route"></el-input>
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item label="上级菜单" prop="superior_menu">
							<el-input style="width: 80%;" v-model="menuDialog.ruleForm.superior_menu"></el-input>
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item label="菜单排序" prop="sort_number">
							<el-input style="width: 80%;" v-model="menuDialog.ruleForm.sort_number"></el-input>
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item label="菜单权限" prop="show_level">
							<el-select style="width: 80%;" v-model="menuDialog.ruleForm.show_level" placeholder="请选择">
								<el-option v-for="data in authorityOption" :key="data.key" :label="data.label"
									:value="data.value"></el-option>
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item label="是否启用" prop="status">
							<el-radio-group v-model="menuDialog.ruleForm.status">
								<el-radio :label="0">启用</el-radio>
								<el-radio :label="1">禁用</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="10">
						<el-form-item>
							<el-button v-if="menuDialog.title == '菜单修改'" type="primary"
								@click="onModifyMenuButtonClick()">确定</el-button>
							<el-button v-if="menuDialog.title == '菜单新增'" type="primary"
								@click="onSubmitAddMenuButtonClick()">新增</el-button>
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
		</el-dialog>
	</div>
</template>

<script>
	import {
		addMenu,
		getMenus,
		updateMenus,
		enabledMenus,
		disableMenus
	} from '../../assets/js/api.js'

	export default {
		data() {
			return {
				id: this.$route.query.id, // 传入的路由id
				user: JSON.parse(sessionStorage.getItem("user")), // 用户信息,请自定义
				authorityOption: this.$globle.authorityOption, // 权限列表,如[{key:"0",label:"游客",value:0},{key:"1",label:"普通用户",value:1},{key:"2",label:"系统管理员",value:2},{key:"3",label:"超级管理员",value:3}]

				menuList: [],

				// 菜单弹窗
				menuDialog: {
					visible: false,
					title: "",
					ruleForm: {
						id: "",
						name: "",
						icon: "1",
						route: "",
						superior_menu: "",
						sort_number: "1",
						show_level: "",
						status: 0
					}
				},
				rules: {
					name: [{
						required: true,
						message: '请输入完整信息',
						trigger: 'blur'
					}],
					icon: [{
						required: true,
						message: '请输入完整信息',
						trigger: 'blur'
					}],
					route: [{
						required: true,
						message: '请输入完整信息',
						trigger: 'blur'
					}],
					superior_menu: [{
						required: true,
						message: '请输入完整信息',
						trigger: 'blur'
					}],
					sort_number: [{
						required: true,
						message: '请输入完整信息',
						trigger: 'blur'
					}],
					show_level: [{
						required: true,
						message: '请输入完整信息',
						trigger: 'blur'
					}],
					status: [{
						required: true,
						message: '请输入完整信息',
						trigger: 'blur'
					}]
				}
			};
		},
		created() {
			this.getMenuList();
		},

		methods: {
			getMenuList() {
				let params = {
					level: this.user.level,
					querySubMenus: true
				}
				getMenus(params).then((res) => {
					this.menuList = res.data
				});
			},

			//启用菜单
			enabledMenu(scope) {
				this.$confirm('确定启用该菜单吗, 是否继续?', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					let param = {
						id: scope.row.id,
						status: 0,
						syncSubMenus: true
					}
					enabledMenus(param).then((res) => {
						this.getMenuList();
					})
				}).catch(() => {

				})
			},

			//禁用菜单
			disabledMenu(scope) {
				this.$confirm('确定禁用该菜单吗, 是否继续?', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					let param = {
						id: scope.row.id,
						status: 1,
						syncSubMenus: true
					}
					enabledMenus(param).then((res) => {
						this.getMenuList();
					})
				}).catch(() => {

				})
			},

			// 修改
			onOpenModifyMenuDialogButtonClick(scope) {
				this.menuDialog.title = "菜单修改";
				this.menuDialog.visible = true;
				this.menuDialog.ruleForm.id = scope.row.id;
				this.menuDialog.ruleForm.name = scope.row.name;
				this.menuDialog.ruleForm.icon = scope.row.icon;
				this.menuDialog.ruleForm.route = scope.row.route;
				this.menuDialog.ruleForm.superior_menu = scope.row.superior_menu;
				this.menuDialog.ruleForm.sort_number = scope.row.sort_number;
				this.menuDialog.ruleForm.show_level = scope.row.show_level;
				this.menuDialog.ruleForm.status = scope.row.status;
			},

			onModifyMenuButtonClick() {
				this.$refs["ruleForm"].validate((valid) => {
					if (valid) {
						this.$confirm('确定修改菜单吗, 是否继续?', '提示', {
							confirmButtonText: '确定',
							cancelButtonText: '取消',
							type: 'warning'
						}).then(() => {
							let param = {
								id: this.menuDialog.ruleForm.id,
								name: this.menuDialog.ruleForm.name,
								icon: this.menuDialog.ruleForm.icon,
								route: this.menuDialog.ruleForm.route,
								superior_menu: this.menuDialog.ruleForm.superior_menu,
								sort_number: this.menuDialog.ruleForm.sort_number,
								level: this.menuDialog.ruleForm.show_level,
								status: this.menuDialog.ruleForm.status
							}
							updateMenus(param).then((res) => {
								if (res.code == "200") {
									this.$message({
										message: res.msg,
										type: "success",
									});
									this.getMenuList();
									this.closeMenuDialog();
								} else {
									this.$message({
										message: res.msg,
										type: "warning"
									});
								}
							})
						}).catch(() => {
							// 添加错误捕获
						})
					} else {
						return false;
					}
				});
			},

			// 新增
			onOpenAddMenuDialogButtonClick() {
				this.menuDialog.title = "菜单新增";
				this.menuDialog.visible = true;
				this.menuDialog.ruleForm.id = "";
				this.menuDialog.ruleForm.name = "";
				this.menuDialog.ruleForm.icon = "";
				this.menuDialog.ruleForm.route = "";
				this.menuDialog.ruleForm.superior_menu = "";
				this.menuDialog.ruleForm.sort_number = "";
				this.menuDialog.ruleForm.show_level = "";
				this.menuDialog.ruleForm.status = 0;
			},

			onSubmitAddMenuButtonClick() {
				this.$refs["ruleForm"].validate((valid) => {
					if (valid) {
						this.$confirm('确定新增菜单吗, 是否继续?', '提示', {
							confirmButtonText: '确定',
							cancelButtonText: '取消',
							type: 'warning'
						}).then(() => {
							let param = {
								name: this.menuDialog.ruleForm.name,
								icon: this.menuDialog.ruleForm.icon,
								route: this.menuDialog.ruleForm.route,
								superior_menu: this.menuDialog.ruleForm.superior_menu,
								sort_number: this.menuDialog.ruleForm.sort_number,
								level: this.menuDialog.ruleForm.show_level,
								status: this.menuDialog.ruleForm.status
							}
							addMenu(param).then((res) => {
								if (res.code == "200") {
									this.$message({
										message: res.msg,
										type: "success",
									});
									this.getMenuList();
									this.closeMenuDialog();
								} else {
									this.$message({
										message: res.msg,
										type: "warning"
									});
								}
							})
						}).catch(() => {
							// 添加错误捕获
						})
					} else {
						return false;
					}
				});
			},

			onCloseMenuDialogButtonClick() {
				this.closeMenuDialog();
			},


			closeMenuDialog() {
				this.$refs['ruleForm'].resetFields();
				this.menuDialog.title = "";
				this.menuDialog.visible = false;
				this.menuDialog.ruleForm.id = "";
				this.menuDialog.ruleForm.name = "";
				this.menuDialog.ruleForm.icon = "";
				this.menuDialog.ruleForm.route = "";
				this.menuDialog.ruleForm.superior_menu = "";
				this.menuDialog.ruleForm.sort_number = "";
				this.menuDialog.ruleForm.show_level = "";
				this.menuDialog.ruleForm.status = 0;
			},


			handleSizeChange(val) {

			},

			handlePageChange(val) {

			}
		},
	}
</script>

<style>
</style>
SpringBoot整合SpringSecurity实现权限控制(六):菜单管理 系列文章目录 《SpringBoot整合SpringSecurity实现权限控制(一):实现原理》 《SpringBoot整合SpringSecurity实现权限控制(二):权限数据基本模型设计》 《SpringBoot整合SpringSecurity实现权限控制(三):前端动态装载路由与菜单》 《SpringBoot整合SpringSecurity实现权限控制(四):角色管理》 《SpringBoot整合SpringSecurity实现权限控制(五):用户管理》 本文目录一、前言二、需求分析三、后端 阅读详情

相关推荐

【Springboot+Vue】做一个权限管理后台(七):动态加载后台菜单

效果演示 数据库设计 每一个用户都有一个用户id,为了对他们进行后台菜单的动态设计,即每个用户看到的的菜单是不一样的,那么我们就要为每一个用户规定一个角色,这就引入了role表,通过user_role的表建立联系。 同样的,每个角色看到不用的菜单,菜单由后端根据登录的角色向数据库查询生成,这就引入了menu表,用过role_menu的表建立联系。 我们插入几个数据: path:代表前端路由的...

qq_42241722的博客 3459

Vue中二级菜单的实现

Vue中二级菜单的实现

Miketutu的博客 5476

用若依框架快速开发一个CMS栏目管理模块(SpringBoot+Vue3实战)

本文详细介绍了如何利用若依框架(RuoYi)快速开发CMS栏目管理模块的全栈实践。通过SpringBoot+Vue3技术栈,从数据库设计到前后端联调,实现高效的企业级应用开发,特别适合需要快速构建稳定、可扩展系统的开发团队。

weixin_30566063的博客 448

如何实现Vue路由的二级菜单

当朋友们看到这个文章时想必是想要了解vue路由二级菜单相关的知识,这里同时多从个角度为大家介绍vue二级路由的配置相应的内容。

青春木鱼的博客 5172

一个炫酷的 springboot 后台模板,有菜单,权限,用户 管理的基本功能

一个后台管理系统,包含有菜单管理,比如新增、删除、修改菜单,同理有权限,用户多角色管理,多样报表,饼图,线形图,柱形图等 ,还有登录校验,当天登录次数过多限制,ip登录过多限制。等基本功能。后续可根据业务需求扩展。

离线安装PlutoSDR硬件支持包全攻略:没有MathWorks账号也能搞定MATLAB集成

本文详细介绍了在没有MathWorks账号和网络环境的情况下,如何离线安装PlutoSDR硬件支持包并实现MATLAB集成的完整解决方案。从驱动安装、设备识别到MATLAB支持包的离线部署,提供了全面的步骤指导和常见问题排查方法,特别适合高校实验室、军工单位等内网环境使用。

js777的博客 265

[Springboot+Vue]做一个权限管理后台(七):动态加载后台菜单

文章目录数据库设计前端设计后端设计 数据库设计 每一个用户都有一个用户id,为了对他们进行后台菜单的动态设计,即每个用户看到的菜单是不一样的,那么我们就要为每一个用户规定一个角色,这就引入了role表,通过user_roler的表建立联系。 同样的,每个角色看到不同的菜单,菜单由后端根据登录的角色向数据库查询生成,这就引入了menu表,通过role_menu的表建立联系。 我们插入几个号数据: ...

WuKongHeBaJie的博客 1488

【单片机】STM32F103C8T6 最小系统板原理图

STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器,由STMicroelectronics(ST)公司生产。它是STMicroelectronics的STM32系列微控制器中的一员,被广泛应用于嵌入式系统和电子设备中。LQFP48封装(Low-profile Quad Flat Package,48引脚)SRAM(静态随机访问存储器):20 KB。支持JTAG调试和编程接口(可选)多个通用输入/输出口(GPIO)USB接口(用于USB设备模式)内置调试和编程接口(SWD)

q742971636的博客 6万+

SpringBoot-Shiro-Vue角色管理实现:动态权限分配与菜单控制终极指南

想要构建一个功能完整、权限控制精细的后台管理系统吗?SpringBoot-Shiro-Vue权限管理框架提供了一套完整的解决方案,实现按钮级别的权限控制。这个开源项目通过前后端分离架构,让开发者能够轻松实现动态权限分配与菜单控制。 ## 为什么选择SpringBoot-Shiro-Vue权限管理 SpringBoot-Shiro-Vue是一个基于Spring Boot、Shiro和Vue.js

gitblog_00293的博客 906

神经进化实践:用遗传算法替代反向传播优化神经网络

神经进化用来定义应用于深度学习的特定优化模式。在本节中,我们通过遗传算法优化简单深度学习网络的权重/参数,替换在误差反向传播训练过程中的所用优化器。

盼小辉丶的博客 3577

【图论】系列(七)图论的中心性度量方法及重要性评价指标

图论中的中心性度量方法是用来衡量图中各个节点(或顶点)相对重要性的指标。

qq_30066733的博客 1075

Vue3 + Vite + SpringBoot3 全栈实战:打造可视化仓储管理平台

这个项目是我工作一年后的一次完整技术实践,虽然还有很多可以优化的地方,但整个过程让我收获颇丰。对于刚工作不久的同学,我的建议是:1. 不要怕项目小,关键是把每个功能做完整2. 多写代码,理论知识需要通过实践来巩固3. 学会总结,把遇到的问题和解决方案记录下来4. 保持学习,技术更新很快,要保持好奇心希望这篇文章对你有帮助,如果有问题欢迎在评论区交流!

qq_61639793的博客 805

PyTorch生成式人工智能(3)——使用PyTorch构建神经网络

在本节中,我们使用 PyTorch 在简单数据集上构建了一个神经网络,训练神经网络来映射输入和输出,并通过执行反向传播来更新权重值以最小化损失值,并利用 Sequential 类简化网络构建过程;介绍了获取网络中间值的常用方法,以及如何使用 save、load 方法保存和加载模型,以避免再次训练模型。

盼小辉丶的博客 1万+

企业级文档管理系统的权限设计:如何用SpringBoot RBAC + Vue动态菜单搞定复杂权限?

本文深入探讨了企业级文档管理系统的权限设计,结合SpringBoot RBAC模型与Vue动态菜单实现精细权限控制。从RBAC核心架构、SpringBoot后端实现到Vue前端动态菜单生成,提供了完整的技术方案,助力企业构建安全高效的文档管理系统。

weixin_42641998的博客 104

NAS新玩法!豆瓣与迅雷结合,轻松实现自动下载电影自动追剧功能

NAS新玩法!豆瓣与迅雷结合,轻松实现自动下载电影自动追剧功能

XiaoqiangClub的博客 6383

【局部规划模块轨迹优化算法】Teb_planner规划算法

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对****做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容由于ROS中的局部路径规划器比较老了,所以我推荐大家使用比较新的局部路径规划器teb_local_planner。teb_local_planner是基于弹性时间带碰撞约束的算法,算法将动态障碍物、运行时效、路径平滑性等约束做综合考虑,在复杂环境下有更优秀的表现。

qq_35635374的博客 951

前后端分离项目实战-通用管理系统搭建(前端Vue3+ElementPlus,后端Springboot+Mysql+Redis)第七篇:菜单和路由动态绑定

每个人都有惰性,但不断学习是好好生活的根本,共勉!绿竹入幽径,青萝拂行衣。——《下终南山过斛斯山人宿置酒》

感谢阅读 1941

【WorkBuddy专栏51】Codex与WorkBuddy的底层基因——两条完全不同的AI智能体路线(上)

【WorkBuddy专栏51】Codex与WorkBuddy的底层基因——两条完全不同的AI智能体路线(上)

AI人人懂 2152

前后端分离项目实战-通用管理系统搭建(前端Vue3+ElementPlus,后端Springboot+Mysql+Redis)第六篇:菜单组件实现(MenuBar.vue)

每个人都有惰性,但不断学习是好好生活的根本,共勉!红颜弃轩冕,白首卧松云。——《赠孟浩然》

感谢阅读 680

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

从零跑通大麦抢票:Python 自动化购票脚本实操指南

开售三秒,页面就灰了。手速再快也拼不过服务器,这就是抢票最真实的样子。ticket-purchase 是一套 Python 自动化购票脚本,大麦抢票从选座到提交都能自动完成:Selenium 负责开浏览器,Appium 负责点手机,选城市、挑场次、填观演人这些重复动作全部提前写好,到点开抢时自动执行。 ## 它到底能帮你做什么 不用写代码,把配置填对就行。 - **双端路线**:网页端走 S

gitblog_00058的博客 475

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

前后端分离项目实战-通用管理系统搭建(前端Vue3+ElementPlus,后端Springboot+Mysql+Redis)第五篇:主页布局搭建(菜单栏、工具栏、主页内容)

每个人都有惰性,但不断学习是好好生活的根本,共勉!

感谢阅读 1058

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

RuoYi-Vue搭建(若依)

项目简介、拉取代码、建库建表、修改配置、后端启动、前端启动、项目访问

tongxin_tongmeng的博客 1448

《第24节》SpringBoot3+Vue3实现分配角色和资源界面

本文介绍了如何在SpringBoot3.x项目中实现用户-角色-资源的权限维护功能。主要内容包括: 创建基础关系表base_rbac_relation,采用单表设计存储用户-角色和角色-资源两种关系 定义关系类型枚举类BaseRbacCategoryEnum统一管理关系类型 实现用户分配角色功能,通过Vue组件assignRole.vue展示角色列表并保存用户-角色关系 提供前后端源码地址,包含完整的权限管理实现方案 文章通过图文结合的方式,展示了用户分配角色和角色分配资源的界面效果,并详细说明了数据库设计

✅ Java 开发工程师 1282

别再手动CRUD了!用若依框架的代码生成器,5分钟搞定SpringBoot+Vue增删改查页面

本文详细介绍了如何利用若依框架的代码生成器快速构建SpringBoot+Vue全栈应用,5分钟内完成传统CRUD开发。通过环境准备、表结构设计、代码生成与集成等步骤,实现高效开发,特别适合企业级项目的二次开发需求。

weixin_29218963的博客 364

如何在RuoYi-Vue权限管理系统中构建企业级文档知识库

企业信息化建设中,团队协作效率往往受制于文档管理的混乱——敏感资料泄露、信息分散存储、版本失控等问题屡见不鲜。RuoYi-Vue作为基于SpringBoot+Vue的前后端分离权限管理系统,虽未原生集成Confluence类文档管理功能,但其完善的权限体系为构建企业级知识库提供了坚实基础。本文将为您揭示如何利用RuoYi-Vue的现有架构,快速搭建安全可控的文档管理系统。 ## 问题导入:企业文

gitblog_01071的博客 355

html管理人权限代码,Spring Boot+Spring Security+Vue的前后端分离的的RBAC权限管理系统Pre...

系统介绍Pre基于Spring Boot 、Spring Security 、Vue的前后端分离的的RBAC权限管理系统,项目支持数据权限管理,支持后端配置菜单动态路由, 第三方社交登录,努力做最简洁的后台管理系统。基于 Spring Boot 2.1.7 、Spring Security 的RBAC权限管理系统基于 Vue UI框架 Element-ui作为 Mybatis Plus 学习与生产...

weixin_30129025的博客 260
上一篇: VUE:SpringBoot + Vue 尝鲜,PDF转换例子
下一篇: VUE:el-autocomplete clearable 提示框无法显示
胖胖的战士
博客等级 码龄18年 104粉丝 98原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值