使用 Blazor 开发内部后台(四):基于Card组件快速搭建导航首页

James: 本系列为大家介绍如何使用 Blazor 来开发管理后台,有兴趣的朋友欢迎跟着实验,体验 Blazor 开发的高效与乐趣。

本系列目录:

  1. 使用 Blazor 开发内部后台(一):认识Blazor

  2. 使用 Blazor 开发内部后台(二):了解 Blazor 组件

  3. 使用 Blazor 开发内部后台(三):登录


前言

很多后台管理系统会采用侧边栏或上方导航组件来实现导航功能,其实也不复杂,但本文介绍另一种简单直接的选择:仍使用上中下三层布局,单独写一个Home页面用于导航。这样的好处在于Home首页或Layout组件里,不用写嵌套的结构和处理导航组件的点击事件。

Card组件

请读者先自行参考Antd Blazor文档:网格型内嵌卡片。Card本身是非常简单的展示组件,而网格型内嵌卡片,可以方便我们快速搭建一个布局整齐的导航栏。先展示一下页面:

卡片导航

Card的Title用来作为类别的主题,下方的子卡片则展示具体的页面链接。这样每个页面的基础代码如下:

<Card Title="分类主题名称" Bordered="true"><CardGrid Style="width: 25%; text-align: center; padding: 0 5px; background-color: whitesmoke;" Hoverable="true"><a href="/MyUrl1" style="font-size:20px">要导航的页面名1</a></CardGrid><CardGrid Style="width: 25%; text-align: center; padding: 0 5px; background-color: whitesmoke;" Hoverable="true"><a href="/MyUrl2" style="font-size:20px">要导航的页面名2</a></CardGrid>
</Card>

配置和动态化

随着时间的推进,后台管理系统通常会加入越来越多的功能,因此也要求导航栏的内容可以根据配置动态展示。

如果使用上述Card组件,则可以很直观地定义一个Json数据结构:

[{"Title": "用户管理","Items": [{"Name": "列表查询","Route": "/user/list","Disabled": true}]},{"Title": "图书管理","Items": [{"Name": "列表查询","Route": "/book/list"}]},{"Title": "音频管理","Items": [{"Name": "列表查询","Route": "/video/list","Disabled": true}]},{"Title": "新闻管理","Items": [{"Name": "列表查询","Route": "/news/list"}],"Hide": true},{"Title": "统计分析","Items": [{"Name": "登录相关","Route": "/analysis/login","Disabled": false},{"Name": "图书相关","Route": "/analysis/book","Disabled": true},{"Name": "音频相关","Route": "/analysis/video","Disabled": true},{"Name": "新闻相关","Route": "/analysis/news","Disabled": true}]}
]

这里我增加了额外的Hide和Disabled字段,Hide字段决定是否显示某个主题,而Disabled字段决定是否启用某个页面的导航链接(但不隐藏)。对应的Model类如下:

    public class HomePageContent{public string Title { get; set; }public HomePageContentItem[] Items { get; set; }public bool Hide { get; set; }}public sealed class HomePageContentItem{public string Name { get; set; }public string Route { get; set; }public bool Disabled { get; set; }}

接着我们要设计如何让Blazor收到这样的配置内容,我们可以让后端以Http接口的方式提供,但我这里介绍一种更直接的办法,供读者参考:

在Blazor项目wwwroot文件夹下创建一个uidata文件夹,在里面再创建一个home文件夹,然后创建一个叫navLinks.json的静态文件用于存储上述的Json数据。

在Blazor项目Services文件夹(没有的话自己创建一个),定义一个接口:

    public interface IUserInterfaceDataService{Task<HomePageContent[]> LoadHomePageContentsAsync();}

该接口封装所有类似静态文件的访问请求,符合高内聚低耦合的设计。现在添加一个具体类:

    internal class UserInterfaceDataService : IUserInterfaceDataService{private const string Root = "/uidata/";private readonly HttpClient _client;public UserInterfaceDataService(HttpClient client){_client = client;}public Task<HomePageContent[]> LoadHomePageContentsAsync() => GetAsync<HomePageContent>("home/naviLinks.json");private async Task<T[]> GetAsync<T>(string path){var data = await _client.GetFromJsonAsync<T[]>(Root + path);return data;}}

再次提醒:别忘了依赖注入!

之后,我们让home.razor页面在初始化时,先访问静态文件naviLinks.json,然后再根据该文件里的Json数据展示首页内容。在home.razor.cs里,加入代码:

    public partial class Home{private HomePageContent[] _contentList = Array.Empty<HomePageContent>();protected async override Task OnInitializedAsync(){_contentList = await UIDataService.LoadHomePageContentsAsync();}}

数据可以获取了,那么如何依赖这样的结构动态生成页面呢?Razor语法的易用性就体现出来了:

@page "/home"
@inject HttpClient Http
@inject IUserInterfaceDataService UIDataService<div style="margin:40px">@foreach (var content in _contentList){@if (!content.Hide){<div style="margin:20px 0"><Card Title=@content.Title Bordered="true">@foreach (var item in content.Items){<CardGrid Style="width: 25%; text-align: center; padding: 0 5px; background-color: whitesmoke;" Hoverable="@(!item.Disabled)">@if (item.Disabled){<span style="font-size:20px;color:dimgray">@item.Name</span>}else{<a href=@item.Route style="font-size:20px">@item.Name</a>}</CardGrid>}</Card></div>}}
</div>

基于@if和@for关键词,可以非常简单地实现HTML代码的动态生成。

现在我们访问首页,Blazor就可以根据静态文件的配置内容动态生成页面了。静态文件的更新不需要重启后端程序,因此首页导航栏的更新对用户和后端来说,都是无感的。有的读者担心浏览器可能会缓存静态文件,导致配置更新不及时——解决办法有很多,例如可以将每次静态文件的请求链接加入一个时间戳的请求参数(.../navLinks.json?t=xxx),或者干脆让用户清除浏览器页面缓存(毕竟只是内部用的后台)。

结束语

下一篇文章准备介绍一下如何使用Antd Blazor组件搭建后台系统中常见的“条件搜索+列表展示”页。不过本月杂事很多,应该要过些日子再更了。

今天是八一建军节,“聚是一团火,散是满天星”,祝现役、退役的所有军人朋友们节日快乐!祝伟大的祖国繁荣昌盛!


欢迎加入 Blazor 中文社区,共同建设热爱的技术社区!

QQ群:1012762441

微信群:JamesYengMVP(加我邀请)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299520.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《西河大鼓——酒色财气》(艳桂荣音配像)

《西河大鼓——酒色财气》&#xff08;唱词文本&#xff09;[url]http://qinyezhai.blog.51cto.com/179831/106820[/url]这是艳桂荣先生根据1998年本人录音于2000年由本人配像&#xff0c;时年72岁&#xff01;转载于:https://blog.51cto.com/qinyezhai/106822

LOOP WITH CONTROL 用法

LOOP - WITH CONTROL Syntax 语法LOOP [AT itab INTO wa [CURSOR top_line] [FROM n1] [TO n2]] WITH CONTROL contrl. ... ENDLOOP. Variants: 变式1. LOOP WITH CONTROL contrl. 2. LOOP AT itab CURSOR cur INTO wa [CURSOR top_line] [FROM n1] [TO n2] …

位操作

1. 改变符号&#xff1a;取反1 2. 与0异或保持不变&#xff0c;与-1(0xffffffff)异或相当于取反。 3. 负数右移可以认为是补符号位&#xff08;当然也有机器不是这样子&#xff09;。负数右移31位就是-1. 1 int sign(int n) {2 return ~n 1;3 }4 5 int abs(int n) {6 …

2020年,朋友圈的正确打开方式!

全世界只有3.14 % 的人关注了青少年数学之旅各位读者朋友们大家好 我是你们的小伙伴上流君我们开始不定期做互推了不是广告&#xff0c;根据兴趣关注感谢理解与支持ღ( &#xff65;ᴗ&#xff65; )比心有些人&#xff0c;生活离不开朋友圈。朋友圈是他们展示自我、观察世界的…

因为我把JMM原理讲解了一遍,这给足了我涨薪的底气!

一、什么是JMM&#xff1f; JMM指的是Java内存模型&#xff0c;即 Java Memory Model Java内存模型并不是一种实际存在的东西&#xff0c;而是一种人为形成的约定&#xff0c;是一种概念。 关于JMM&#xff0c;我们需要了解一些相关的同步约定 &#xff1a; 线程在解锁前&…

防腐投加器需要加盐吗_果干、果脯、蜜钱、水果脆片,哪个有营养?你吃对了吗?...

时下&#xff0c;追求健美瘦身的年轻人&#xff0c;常把水果千作为零食、加餐的选择之一。大家认为水果干不仅味道好&#xff0c;富含营养素&#xff0c;而且热量低。还有一些人会把果脯、蜜钱、水果脆片等当作新鲜水果的替代品&#xff0c;用以补充营养一认为果 脯、蜜钱的原料…

.NET6正式版将近,70%开发者或面临技术断层!

过往一周&#xff0c;VS2019 发布了最新V16.11&#xff0c;正式支持热重载&#xff1b;.NET6发布了最后一个预览版Preview7&#xff0c;各大新功能宣告完成&#xff1b;随之C#10的新特性也基本成型&#xff0c;好东西很多&#xff01;各种密集的版本更新&#xff0c;佐证了行业…

谈谈分布式事务(Distributed Transaction)[共5篇]

[第1篇] SOA需要怎样的事务控制方式 在一个基于SOA架构的分布式系统体系中&#xff0c;服务&#xff08;Service&#xff09;成为了基本的功能提供单元&#xff0c;无论与业务流程无关的基础功能&#xff0c;还是具体的业务逻辑&#xff0c;均实现在相应的服务之中。服务对外提…

软件方面的词汇

1 SaaS是Software-as-a-service&#xff08;软件级服务&#xff09; SaaS提供商为企业搭建信息化所需要的所有网络基础设施及软件、硬件运作平台&#xff0c;并负责所有前期的实施、后期的维护等一系列服务&#xff0c;企业无需购买软硬件、建设机房、招聘IT人员&#xff0c;即…

一只蝙蝠的自述在朋友圈火了:千万不要再吃野味了!

全世界只有3.14 % 的人关注了青少年数学之旅来源&#xff1a;少女兔&#xff08;ID&#xff1a;iiilass&#xff09;、人民日报&#xff08;ID&#xff1a;rmrbwx&#xff09;从营养价值上来看野生动物和家养动物的差别微乎其微既不能延年益寿&#xff0c;也不能青春永驻它们不…

转载:xml文件中的特殊字符

在XML文档中预定义好的实体: < < 小于号 > > 大于号 &amp; & 和 &apos; 单引号 &quot; " 双引号 实体必须以符号"&"开头&#xff0c;以符号";"结尾。 注意: 只有"<" 字符和"&am…

掌握JVM 运行时数据区,其实不是很难,加薪也是要技巧可言的!!!

一、概念 Java 内存区域和内存模型是不一样的东西&#xff0c;内存区域是指 Jvm 运行时将数据分区域存储&#xff0c;强调对内存空间的划分。 而内存模型&#xff08;Java Memory Model&#xff0c;简称 JMM &#xff09;是定义了线程和主内存之间的抽象关系&#xff0c;即 J…

不要被约束的意思_俗话说:“娶妻不娶颧骨高,嫁汉不嫁连眉梢”,到底什么意思?...

“世有伯乐&#xff0c;然后有千里马。千里马常有&#xff0c;而伯乐不常有。”——《杂说》 唐韩愈传说春秋时期&#xff0c;有个叫伯乐的人很会选马&#xff0c;他选马的时候&#xff0c;并不需要骑着马真刀真枪地跑几圈&#xff0c;只是看看马的骨相、听听马的嘶鸣就能判断出…

终于来了!微软正式推出 VS Code 测试 API

随着 Visual Studio Code 1.59.0 正式版本的发布&#xff0c;全新的插件测试 API 也从试验版本进入了正式版本。自 2020 年 9 月起至今&#xff0c;经过了将近一年及数次版本迭代的打磨&#xff0c;不管是 API 的功能性还是易用性&#xff0c;与首个预览版本相比都获得了极大的…

发布软件之前,怎样告诉用户怎么用

这几年&#xff0c;大大小小的做过十来个项目&#xff0c;软件做好了&#xff0c;怎样告诉别人你的工作成果呢&#xff1f; 我的经验适合于公司内部项目&#xff0c;不适合向外发布的面对像上帝一样的客户的项目。 有几个项目是公司内部项目&#xff0c;虽然大家平时沟通的邮件…

MariaDB 10的复制 集群 高可用搭建 大表拆分【持续更新中】

视频地址 http://edu.51cto.com/course/course_id-1691.htmlMariaDB 10培训课程第一部分 复制1.基于GTID方式复制配置及注意事项2.基于表的并行复制3.多源复制&#xff08;MariaDB 10支持多主一从&#xff09;4.从库延迟如何找到那条执行慢的SQL5.复制异常处理1062,1032错误处理…

c++歌手大赛系统_计人即讯|第十届程序设计大赛

“第十届程序设计大赛”为激发学生学习计算机语言和科学使用计算机的热情&#xff0c;培养独立思考、勇于创新的探索精神和敢闯会创的意志品格&#xff0c;我院于12月5日13时30分在中主阶教201室成功举办了“第十届程序设计大赛”。本次大赛主要考察选手们应用计算机解决生活中…

限时9.9元 | 快速领取数学建模竞赛备战必备技巧与论文详解!

全世界只有3.14 % 的人关注了青少年数学之旅大家晚上好&#xff0c;随着美赛时间的公布以及大大小小的数学建模竞赛的进行&#xff0c;小天经常可以收到来自很多小伙伴们提出的问题&#xff0c;“竞赛中如何去考虑选题&#xff1f;”、“如何进行思路分析&#xff1f;”、“参考…

项目经理问我Java内存区域模型!急急急

也就这么点吧 Java内存区域主要分为&#xff1a;堆&#xff0c;栈&#xff0c;方法区三大部分 1、堆&#xff1a;是内存区域中最大的部分&#xff0c;所有线程共享&#xff0c;其中存放创建的对象和数组。由于堆是垃圾收集器管理的主要区域&#xff0c;因此也叫GC堆。 2、栈…