无论用什么框架,第一件事情就是实现动态菜单,从数据库中读取菜单配置项输出前台,网上翻了一大堆翻译文档,也看了官方英文文档,关键点在于如何实现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. 虚拟机Ubuntu系统无法连接网络解决方案

    宿主机连接wifi,虚拟机无法联网 查看是否有网络图标 操作一: sudo service network-manager stopsudo rm /var/lib/NetworkManager/Ne ...

  2. Https工作流程图

  3. Mycat分布式数据库架构解决方案--Linux安装运行Mycat

    echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! Myc ...

  4. redis面试题及答案

    1. Redis有哪些数据结构? 2. 使用过Redis分布式锁么,它是什么回事? 3. 假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来? ...

  5. SpringBoot + Redis 执行lua脚本

    1.背景 有时候,我们需要一次性操作多个 Redis 命令,但是 这样的多个操作不具备原子性,而且 Redis 的事务也不够强大,不支持事务的回滚,还无法实现命令之间的逻辑关系计算.所以,一般在开发中 ...

  6. 永恒之蓝复现(win7/2008)

    Kali对Windows2008/7的MS17010漏洞测试(MSF自带模块) 0x01 说明 其实这个MSF自带的exp模块还是挺让人伤脑筋的,因为它支持的OS并不是很多,也就Windows Ser ...

  7. 学习笔记66_DBSCAN聚类算法

  8. python-->二进制的用法

    1.10进制转换为其他进制 方法一:函数 十进制转二进制:bin(10) --> '0b1010' tpye:是字符串类型 0b:表示2进制 十进制转八进制:oct(10) --> '0o ...

  9. scss新手使用指南

    还在用死的css写样式吗?那可太麻烦了,各种长串选择器不说,还有各种继承权重有时候还有可能不生效 我的小程序项目也结束了,是时候总结一下scss语法了,毕竟用起来更加方便而且还能精简一点代码,好处多多 ...

  10. js实现列表从下往上循环滚动

    html: <div class="liscorll"> <ul> <li>内容</li> </ul> </div ...