用 PartialView作为左侧菜单项,进行动态加载
1. 作品展示
![]()
2. 定义菜单数据模型
// Models/MenuItem.cspublicclassMenuItem{publicintId{get;set;}publicstringName{get;set;}// 菜单名称publicstringIcon{get;set;}// 图标(例如:layui-icon layui-icon-face)publicstringUrl{get;set;}// 点击后打开的页面地址publicintParentId{get;set;}// 父级ID,用于构建树形结构publicintSortOrder{get;set;}// 排序publicList<MenuItem>Children{get;set;}=newList<MenuItem>();}
3. 控制器实现
publicclassHomeController:Controller{privatereadonlyILogger<HomeController>_logger;publicHomeController(ILogger<HomeController>logger){_logger=logger;}publicIActionResultIndex(){returnView();}// 获取左侧菜单的 PartialViewpublicasyncTask<IActionResult>GetLeftMenu(){// 模拟从数据库获取菜单数据(实际开发中请从Service获取)varmenuList=awaitGetMenuDataAsync();// 构建树形结构varmenuTree=BuildTree(menuList,0);returnPartialView("_LeftMenu",menuTree);}// 模拟数据源privateTask<List<MenuItem>>GetMenuDataAsync(){varmenus=newList<MenuItem>{newMenuItem{Id=1,Name="仪表盘",Icon="layui-icon-home",Url="/Home/Dashboard",ParentId=0,SortOrder=1},newMenuItem{Id=2,Name="系统管理",Icon="layui-icon-set",Url="#",ParentId=0,SortOrder=2},newMenuItem{Id=3,Name="用户管理",Icon="layui-icon-user",Url="/User/Index",ParentId=2,SortOrder=1},newMenuItem{Id=4,Name="角色管理",Icon="layui-icon-group",Url="/Role/Index",ParentId=2,SortOrder=2},newMenuItem{Id=5,Name="日志管理",Icon="layui-icon-log",Url="/Log/Index",ParentId=2,SortOrder=3}};returnTask.FromResult(menus);}// 构建树形结构privateList<MenuItem>BuildTree(List<MenuItem>source,int?parentId){returnsource.Where(x=>x.ParentId==parentId).OrderBy(x=>x.SortOrder).Select(x=>newMenuItem{Id=x.Id,Name=x.Name,Icon=x.Icon,Url=x.Url,ParentId=x.ParentId,SortOrder=x.SortOrder,Children=BuildTree(source,x.Id)}).ToList();}}
4. 主视图 (Views/Home/Index.cshtml)
@{ Layout = null; }<!DOCTYPEhtml><html><head><metacharset="utf-8"><metaname="viewport"content="width=device-width, initial-scale=1"><title>ASP.NET Core + Layui 后台管理</title><linkrel="stylesheet"href="~/lib/layui/css/layui.css"/><style>/* 自定义样式 */.layui-layout-admin .layui-body{bottom:0;overflow:hidden;}.layui-tab-content{height:calc(100vh - 110px);padding:0;}.layui-tab-item{height:100%;}iframe{width:100%;height:100%;border:none;}</style></head><bodyclass="layui-layout-body"><divclass="layui-layout layui-layout-admin"><!-- 顶部导航栏 --><divclass="layui-header"><divclass="layui-logo">后台管理系统</div><ulclass="layui-nav layui-layout-right"><liclass="layui-nav-item"><ahref="javascript:;"><imgsrc="~/images/default-avatar.png"class="layui-nav-img">管理员</a><dlclass="layui-nav-child"><dd><ahref="">基本资料</a></dd><dd><ahref="">修改密码</a></dd><dd><aasp-action="Logout"asp-controller="Account">退出</a></dd></dl></li></ul></div><!-- 左侧菜单容器 --><divclass="layui-side layui-bg-black"id="leftMenuContainer"><divclass="layui-side-scroll"><!-- 这里将通过 Ajax 加载 PartialView --><divid="menuLoading"style="text-align:center;padding:20px;color:#ccc;"><iclass="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i>加载菜单中...</div></div></div><!-- 右侧主体内容:Layui 选项卡容器 --><divclass="layui-body"><divclass="layui-tab"lay-filter="tab"lay-allowClose="true"><ulclass="layui-tab-title"><liclass="layui-this"lay-id="home">首页</li></ul><divclass="layui-tab-content"><divclass="layui-tab-item layui-show"><iframesrc="@Url.Action("Welcome","Home")"></iframe></div></div></div></div></div><scriptsrc="~/lib/jquery/dist/jquery.min.js"></script><scriptsrc="~/lib/layui/layui.js"></script><script>layui.use(['element','layer'],function(){varelement=layui.element;varlayer=layui.layer;var$=layui.$;// 加载左侧菜单loadLeftMenu();functionloadLeftMenu(){$.ajax({url:'@Url.Action("GetLeftMenu", "Home")',type:'GET',success:function(html){$('#leftMenuContainer .layui-side-scroll').html(html);// 重新渲染导航菜单element.render('nav');},error:function(){$('#menuLoading').html('<span style="color: #FF5722;">菜单加载失败</span>');}});}// 监听菜单点击事件(通过事件委托)$(document).on('click','.menu-item',function(e){e.preventDefault();varurl=$(this).data('url');varname=$(this).data('name');varid=$(this).data('id')||'tab_'+newDate().getTime();// 判断是否已存在选项卡if($('.layui-tab-title li[lay-id="'+id+'"]').length>0){element.tabChange('tab',id);}else{// 新增选项卡element.tabAdd('tab',{title:name,content:'<iframe src="'+url+'"></iframe>',id:id});element.tabChange('tab',id);}});// 选项卡切换时,可以触发 iframe 的刷新(可选)element.on('tab(tab)',function(data){console.log('切换到选项卡:'+data.index);});});</script></body></html>
5. 左侧菜单 PartialView (Views/Home/_LeftMenu.cshtml)
@model IEnumerable<MenuItem>@functions { // 递归渲染菜单的辅助方法 void RenderMenuItem(MenuItem item) { if (item.Children != null && item.Children.Any()) {<liclass="layui-nav-item"><ahref="javascript:;"><iclass="layui-icon @item.Icon"></i><span>@item.Name</span></a><dlclass="layui-nav-child">@foreach (var child in item.Children) {<dd><ahref="javascript:;"class="menu-item"data-url="@child.Url"data-id="@child.Id"data-name="@child.Name"><iclass="layui-icon @child.Icon"></i>@child.Name</a></dd>}</dl></li>} else {<liclass="layui-nav-item"><ahref="javascript:;"class="menu-item"data-url="@item.Url"data-id="@item.Id"data-name="@item.Name"><iclass="layui-icon @item.Icon"></i><span>@item.Name</span></a></li>} } }<ulclass="layui-nav layui-nav-tree"lay-filter="leftMenu">@foreach (var menu in Model) { @RenderMenuItem(menu) }</ul><style>/* 菜单图标样式 */.layui-nav-item .layui-icon{margin-right:8px;font-size:16px;}/* 子菜单缩进 */.layui-nav-child dd{padding-left:10px;}</style>