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

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 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(加我邀请)

以上是关于使用 Blazor 开发内部后台:基于Card组件快速搭建导航首页的主要内容,如果未能解决你的问题,请参考以下文章

使用 Blazor 开发内部后台:登录

使用Blazor开发内部后台:认识Blazor

通过Blazor使用C#开发SPA单页面应用程序 - Ant Design Button

使用MASA Blazor开发一个标准的查询表格页

基于TDesign风格的Blazor企业级UI组件库

Bootstrap Blazor 实战 Markdown 编辑器使用