• . NET Core Razor动态菜单实现


    准备

    1.框架

       .netcore  版本 yishaadmin开源框架

    2.模板 

       本文模板使用adminlte3.0,文档地址https://adminlte.io/docs/3.0/

    3.菜单表关键字段 

      id 表主键(当前菜单)
      ParentId 父级ID(父级菜单 为0时为顶级菜单,也可能为内容)
      MenuUrl 菜单地址(只有页面有地址,本身菜单是空)
      MenuType 菜单类型(1是菜单 2是页面 3是按钮)
      MenuIcon 图标样式

    4.菜单表实体

    复制代码
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using YiSha.Util;
    
    namespace YiSha.Entity.SystemManage
    {
        [Table("SysMenu")]
        public class MenuEntity : BaseExtensionEntity
        {
            [JsonConverter(typeof(StringJsonConverter))]
            public long? ParentId { get; set; }
    
            public string MenuName { get; set; }
    
            public string MenuIcon { get; set; }
    
            public string MenuUrl { get; set; }
    
            public string MenuTarget { get; set; }
    
            public int? MenuSort { get; set; }
    
            public int? MenuType { get; set; }
    
            public int? MenuStatus { get; set; }
            public string Authorize { get; set; }
    
            public string Remark { get; set; }
    
            [NotMapped]
            public string ParentName { get; set; }
        }
    }
    复制代码

    开始开发

      本文是由于框架内置菜单不支持顶级菜单显示为内容,以及菜单最多只支持三级菜单的问题,故进行了调整。

    1.实现思路

       下图1区域渲染为菜单,菜单通过点击URL将内容填充到2区域。  

     2.编码

      2.1  建立渲染内容填充方法

             将传进来的url通过ajax调用最终渲染到内容区域(id为#Content的Div中),其中beforeSend方法显示Loadding 可根据需要自行调整。url为{area:exists}/{controller=Home}/{action=Index}以及{controller=Home}/{action=Index}根据框架配置填写至菜单

    复制代码
      function LoadContent(url) {
            if (url == null || url == "")
                return;
    
            $.ajax({
                url: url,
                beforeSend: function (XHR) {
                    $.blockUI({ message: '<div class="loaderbox"><div class="loading-activity"></div> ' 
    + "加载中..." + '</div>', css: { border: "none", backgroundColor: 'transparent' } }); }, success: function (data) { $("#Content").html(data); setTimeout(function () { $.unblockUI(); }, 100); }, error: function (data, status, e) { $("#Content").html("页面加载失败," + data.status + "," + url + "<br />" + data.responseText); setTimeout(function () { $.unblockUI(); }, 100); } }); }
    复制代码

      2.2  建立分部视图

           通过建立分部视图MenuTree,循环传入的菜单,初始化时先获取父级ID(ParentId)为0并且类别(MenuType)不为按钮的菜单集合进行循环,根据menuEntity.MenuUrl判断是否为页面,如果依然为菜单则使用Html.PartialAsync("MenuTree")调用自身来实现递归,第二次则根据ViewData["Menu"]传入的当前id作为父级id来寻找子集,直到寻找到最后的层级。
    复制代码
    @using System.Collections.Generic
    @using YiSha.Entity.SystemManage;
    @model List<MenuEntity>
    
    
    @{
        if (Model.Any())
        {
            long id = 0L;
            var menu = ViewData["Menu"] as MenuEntity;
            if (menu != null)
              id = menu.Id.Value;
    
            @foreach (var menuEntity in Model.Where(o => o.ParentId == id && o.MenuType != (int)MenuTypeEnum.Button))
            {
                var icno = string.IsNullOrEmpty(menuEntity.MenuIcon) ? "fa fa-comment" : menuEntity.MenuIcon;
                @if (!string.IsNullOrEmpty(menuEntity.MenuUrl))
                {
                   <li class="nav-item">
                       <a href="#" class="nav-link" onclick="LoadContent('@menuEntity.MenuUrl')">
                           <i class="nav-icon @icno"></i>
                           <p>
                               @menuEntity.MenuName
                           </p>
                       </a>
                   </li>
                }
                else
                {
                    ViewData["Menu"] = menuEntity;
                    <li class="nav-item">
                        <a href="#" class="nav-link">
                        <i class="nav-icon @icno"></i>
                        <p>
                            @menuEntity.MenuName
                            <i class="fas fa-angle-left right"></i>
                        </p>
                        </a>
                        <ul class="nav nav-treeview">
                             @await Html.PartialAsync("MenuTree",
                             Model,new ViewDataDictionary(ViewData))
                        </ul>
                   </li>
                }
             }
        }
    }
    复制代码

    2.3 调用分布视图

    复制代码
         <aside class="main-sidebar sidebar-dark-primary elevation-4" style="width:200px;position:fixed">
                <!-- Brand Logo -->
                
                <!-- Sidebar -->
                <div class="sidebar">
    
                    <!-- Sidebar Menu -->
                    <nav class="mt-2">
                        <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
                            <!-- Add icons to the links using the .nav-icon class
        with font-awesome or any other icon font library -->
    
                            <li class="nav-header" style="font-size:1.0rem">
                                <img src="~/yisha/img/logo1.png" style="width: 30px; height: 30px; " />
                                任务管理系统
                            </li>
    
                            @await Html.PartialAsync("MenuTree", Model)
                        </ul>
                    </nav>
                    <!-- /.sidebar-menu -->
                </div>
                <!-- /.sidebar -->
            </aside>
    
            <!-- Content Wrapper. Contains page content -->
            <div class="content-wrapper" id="mainhead">
                <div id="Content">
    
                </div>
            </div>
    复制代码

     

  • 相关阅读:
    Linux 使用root用户给某个用户赋权操作某个文件夹和Oracle导入导出dump文件
    Crypto(4)NewStarCTF 2023 week2 Crypto Rotate Xor
    2022年山东省安全员C证复训题库模拟考试平台操作
    Centos上OpenSSH7-4p1-9-0p1版本升级
    微信小程序Day5笔记
    小程序【云开发】模式基本介绍 | 云开发项目初始化
    JDK8新特性之 stream流
    【国际化Intl】Flutter 国际化多语言实践
    UDS知识整理(六):通讯控制——0x28服务
    申请发明专利的步骤有哪些?
  • 原文地址:https://www.cnblogs.com/zspwf/p/16202890.html