无论用什么框架,第一件事情就是实现动态菜单,从数据库中读取菜单配置项输出前台,网上翻了一大堆翻译文档,也看了官方英文文档,关键点在于如何实现NavigationProvider和在前端调用abp.nav.menus.MainMenu

后台处理

1、建表UiMenu

 public class UiMenu : FullAuditedEntity<int>, IMustHaveTenant
{
public int Pid { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[StringLength(50)]
public string DisplayName { get; set; }
[Required]
[StringLength(50)]
public string MenuType { get; set; }
[StringLength(200)]
public string Path { get; set; }
[StringLength(500)]
public string CustomData { get; set; }
[StringLength(200)]
public string Remark { get; set; }
public string Icon { get; set; }
public string Action { get; set; }
public int Order { get; set; }
public int TenantId { get; set; }
}

2、实现MyNavigationProvider

在Core项目里新建文件夹Navigations,新建类MyNavigationProvider,需继承NavigationProvider

如下实现UiMneu的仓储操作对象

        private readonly IRepository<UiMenu> _repository;
public MyNavigationProvider(IRepository<UiMenu> repository)
{
_repository = repository;
}

然后重写SetNavigation


var allMenus = _repository.GetAllList();
foreach (var item in allMenus)
{
if (item.Pid>0)
{
//子项
context.Manager.MainMenu.GetItemByName(allMenus.Find(p => p.Id == item.Pid).Name).AddItem(
new MenuItemDefinition(
item.Name,
new LocalizableString(item.DisplayName, MyConsts.LocalizationSourceName),
url: item.Path,
icon: item.Icon,
isVisible: item.IsDeleted,
requiredPermissionName: ""
)
);
}
else
{
//父级菜单
context.Manager.MainMenu.AddItem(new MenuItemDefinition(
item.Name,
new LocalizableString(item.DisplayName, MyConsts.LocalizationSourceName),
url: item.Path,
icon: item.Icon,
isVisible:item.IsDeleted,
requiredPermissionName:""//配置权限,可在UiMenu表中新加字段配置
));
}
}

至于如何对菜单表进行增删改查维护,不是本篇主题,故略过。

前端实现

前端实现的主要是依靠官方提供的方法abp.nav.menus.MainMenu

1、创建router帮助方法 router-util.ts


import main from '../views/main.vue'
//import ParentView from '@/components/parent-view'
// 加载路由菜单,从localStorage拿到路由,在创建路由时使用
// @函数: 引入组件
export const lazyLoadingCop = file => require('../views' + file + '.vue').default
class RouterHelper {
dynamicRouterAdd(): Array<Router> {
let dynamicRouter = []
window.abp.nav.menus.MainMenu.items.forEach(el => {
let obj = {
path: '/' + el.name,
name: el.name,
icon: el.icon,
permission: undefined,
meta: { title: el.displayName },
component: 'main',
children: [],
}
if (el.items.length > 0) {
el.items.forEach(child => {
obj.children.push({
path: child.name,
name: child.name,
icon: child.icon,
permission: undefined,
meta: { title: child.displayName },
component: child.url,
children: null,
})
})
dynamicRouter.push(obj)
} else {
dynamicRouter.push({
path: '/' + el.items[0].name,
name: el.items[0].name,
icon: el.items[0].icon,
permission: undefined,
meta: { title: el.items[0].displayName },
component: el.items[0].url,
children: [],
})
}
});
dynamicRouter = this.filterAsyncRouter(dynamicRouter)
return dynamicRouter
} // @函数: 遍历后台传来的路由字符串,转换为组件对象
filterAsyncRouter(asyncRouterMap) {
const accessedRouters = asyncRouterMap.filter(route => {
if (route.component) {
if (route.component === 'main' || route.component.name === 'main') { // Main组件特殊处理
route.component = main
}
// else if (route.component === 'parentView') { // parentView组件特殊处理
// route.component = ParentView
// }
else {
route.component = lazyLoadingCop(route.component)
}
}
if (route.children && route.children.length) {
route.children = this.filterAsyncRouter(route.children)
}
return true
})
return accessedRouters
} }
const routerHelper = new RouterHelper();
export default routerHelper;

parentView为多级菜单,如果有需求可以使用,该组件摘自iView admin 2.0

解释:

循环abp.nav.menus.MainMenu.items,将其格式转换为Router。方便菜单调用。

2、修改router/index.ts

找到router/index.ts,

beforeEach方法里添加如下代码

        let dyRouters = RouterHelper.dynamicRouterAdd()
dyRouters.forEach(element => {
appRouters.push(element);
});
router.addRoutes(appRouters)

注意引用 import RouterHelper from '../lib/router-util'

总结

一开始没有丝毫头绪,后台参照使用iview admin时构建的方法进行尝试,加之刚刚接触typescript,用起来不是特别顺手,问题的关键在于router/router.ts->appRouters处无法获得abp.nav.menus.MainMenu.items在store/modules/app里虽然可以获取,但是router中不存在,无法正常点击跳转,taglist同样也无从获取。

最终想到这种不是很完美的方法,前端仍然需要进行循环转换Model。但终归是实现了动态菜单,可以进行下一步操作了。

【ABP】 动态菜单修改过程asp.netcore+vue的更多相关文章

  1. .net core3.1 abp动态菜单和动态权限(思路) (二)

    ps:本文需要先把abp的源码下载一份来下,跟着一起找实现,更容易懂 在abp中,对于权限和菜单使用静态来管理,菜单的加载是在登陆页面的地方(具体是怎么知道的,浏览器按F12,然后去sources中去 ...

  2. .net core3.1 abp动态菜单和动态权限(动态菜单实现和动态权限添加) (三)

    我们来创建动态菜单吧 首先,先对动态菜单的概念.操作.流程进行约束:1.Host和各个Tenant有自己的自定义菜单2.Host和各个Tenant的权限与自定义菜单相关联2.Tenant有一套默认的菜 ...

  3. 循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理

    在我开发的很多系统里面,包括Winform混合框架.Bootstrap开发框架等系列产品中,我都倾向于动态配置菜单,并管理对应角色的菜单权限和页面权限,实现系统对用户权限的控制,菜单一般包括有名称.图 ...

  4. 【vue】iView-admin2.0动态菜单路由

    vue项目实现动态路由有俩种方式 一.前端在routers中写好--所有--路由表 <前端控制路由>,登录时根据用户的角色权限来动态的显示菜单路由 二.前端通过调用接口请求拿到当前用户-- ...

  5. vue、iview动态菜单(可折叠)

    vue项目与iview3实现可折叠动态菜单. 菜单实现一下效果: 动态获取项目路由生成动态三级菜单导航 可折叠展开 根据路由name默认打开子目录,选中当前项 自动过滤需要隐藏的路由(例:登陆) 在手 ...

  6. 【vue】iView-admin2.0动态菜单路由【版2】

    依照iView-admin2.0动态菜单路由[版1] 归纳几个节点动态路由获取方式2 ——> easymock假数据 ——> 数据转组件处理.addRoutes ——> localS ...

  7. asp.netcore 深入了解配置文件加载过程

    前言     配置文件中程序运行中,担当着不可或缺的角色:通常情况下,使用 visual studio 进行创建项目过程中,项目配置文件会自动生成在项目根目录下,如 appsettings.json, ...

  8. abp添加动态菜单

    abp中MenuDefinition封装了导航栏上的主菜单的属性,MenuItemDefinition则封装了子菜单的属性,子菜单可以引用其他子菜单构成一个菜单树. MenuDefinitio成员如下 ...

  9. ABP+NetCore+Vue.js实现增删改查

    ABP我就不多介绍了,不知道的可以自己百度 本篇开发工具VS2017,数据库SQL SERVER2012,系统Win7 1.去ABP官网下载对应的模板,下载地址:https://aspnetboile ...

随机推荐

  1. NOIP2009 Hankson 的趣味题 : 数论

    题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson.现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题. 今天在课堂上,老师讲解 ...

  2. POJ 3020 Antenna Placement(二分图 匈牙利算法)

    题目网址:  http://poj.org/problem?id=3020 题意: 用椭圆形去覆盖给出所有环(即图上的小圆点),有两种类型的椭圆形,左右朝向和上下朝向的,一个椭圆形最多可以覆盖相邻的两 ...

  3. Vulnhub靶场渗透练习(三) bulldog

    拿到靶场后先对ip进行扫描 获取ip  和端口 针对项目路径爆破 获取两个有用文件 http://192.168.18.144/dev/ dev,admin 更具dev 发现他们用到框架和语言 找到一 ...

  4. git clone下代码window与unix换行问题

    项目中避免不了会写一些shell脚本,使用ln软连接到一个目录.当git clone到windows中,ln连接显示无比怪异(如../xx),打开.sh文件后(仅仅是打开了),git status会看 ...

  5. springboot学习(二十二)_ 使用@Constraint注解自定义验证注解

    最近项目在使用如@NotNull @Max 等配合@vaild 注解进行验证传过来的参数校验,然后通过统一异常处理,直接返回给前端,不用在业务代码中对这些参数进行校验.但是官方提供的并不能全部满足项目 ...

  6. Kubernetes1-K8s的简单介绍

    一.简介 1.什么是Kubernetes 简称K8s,用8代替8个字符“ubernerte”而成的速写,K8s是一个开源的容器编排平台,它是一个跨主机集群的开源容器调度平台,用于管理云平台中多个主机上 ...

  7. 玩转OneNET物联网平台之MQTT服务⑤ —— OneNet智能灯+MVP框架

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  8. 10 python学习笔记-操作数据库(十)

    在功能.接口测试中,常常需要通过数据库的操作,来准备数据.检测环境及核对功能.接口的数据库操作是否正确. 在自动化测试中,就需要我们用代码连接数据库自动完成数据准备. 环境检查及数据库断言的功能.数据 ...

  9. LNMP与LAMP的工作原理

    LAMP的实现原理 LAMP=Linux+Apache+Mysql+PHP.​#工作原理:浏览器向服务器发送http请求,服务器 (Apache) 接受请求,由于php作为Apache的组件模块也会一 ...

  10. 页面报错常用状态码总结(Http常见状态码)

    作为一个互联网开发人员对于一些服务器返回的HTTP状态的意思都必须是了如指掌的,只有将这些状态码一一弄清楚,工作中遇到的各种问题才能够处理的得心应手.好了,下面就让我们来了解一下比较常见的HTTP状态 ...