基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
1|0系列文章
- 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目
- 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来
- 基于 abp vNext 和 .NET Core 开发博客项目 - 完善与美化,Swagger登场
- 基于 abp vNext 和 .NET Core 开发博客项目 - 数据访问和代码优先
- 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查
- 基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型
- 基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁
- 基于 abp vNext 和 .NET Core 开发博客项目 - 接入GitHub,用JWT保护你的API
- 基于 abp vNext 和 .NET Core 开发博客项目 - 异常处理和日志记录
- 基于 abp vNext 和 .NET Core 开发博客项目 - 使用Redis缓存数据
- 基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理
- 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(四)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目
上一篇完成了博客文章详情页面的数据展示和基于JWT方式的简单身份验证,本篇继续推进,完成后台分类管理的所有增删改查等功能。
2|0分类管理
在 Admin 文件夹下新建Razor组件,Categories.razor
,设置路由,@page "/admin/categories"
。将具体的展示内容放在组件AdminLayout
中。
在这里我会将所有分类展示出来,新增、更新、删除都会放在一个页面上去完成。
先将列表查出来,添加API的返回参数,private ServiceResult<IEnumerable<QueryCategoryForAdminDto>> categories;
,然后再初始化中去获取数据。
初始化的时候,需要将我们存在localStorage
中的token读取出来,因为我们后台的API都需要添加 Authorization
Header 请求头才能成功返回数据。
在Blazor添加请求头也是比较方便的,直接Http.DefaultRequestHeaders.Add(...)
即可,要注意的是 token值前面需要加 Bearer
,跟了一个空格不可以省略。
获取数据单独提成了一个方法FetchData()
,因为会频繁用到,现在在页面上将数据绑定进行展示。
同样的当categories还没成功获取到数据的时候,我们直接在展示 <Loading />
组件。然后就是循环列表数据在foreach
中进行绑定数据。
在每条数据最前面,加了删除和编辑两个按钮,删除的时候调用DeleteAsync
方法,将当前分类的Id传给他即可。新增和编辑的时候调用ShowBox
方法,他接受一个参数,当前循环到的分类对象item,即QueryCategoryForAdminDto
。
同时这里考虑到复用性,我写了一个弹窗组件,Box.Razor
,放在Shared文件夹下面,可以先看一下标题为弹窗组件的内容再回来继续往下看。
2|1删除分类
接下来看看删除方法。
删除之前搞个原生的confirm
进行提示,避免手残误删。因为API那边使用的是HttpDelete
,所有我们调用API时候要用Http.DeleteAsync
,返回的是HttpResponseMessage
对象,需要我们手动处理接收返回数据,将其转换为ServiceResult
对象,如果判断删除成功后重新调用FetchData()
刷新分类数据。
2|2新增/更新分类
新增和更新数据选择使用弹窗的方式来进行(弹窗组件在下方),首先是需要一个参数判断弹窗是否打开,因为是将新增和更新放在一起,所以如何判断是新增还是更新呢?这里使用Id来进行判断,当编辑的时候肯定会有Id参数。新增的时候是没有参数传递的。
当我们打开弹窗后里面需要展示两个input框,用来供输入要保存的数据,同样是添加两个变量。
添加所需的这几个参数。
现在可以将Box组件添加到页面上。
确定按钮回调事件执行SubmitAsync()
方法,打开状态参数为上面添加的Open
,按钮文字ButtonText
为默认值不填。
添加了两个input,将两个分类字段分别绑定上去,使用@bind
和@bind:event
。前者等价于设置其value值,后者等价于一个change事件当值改变后会重新赋给绑定的字段参数。
现在可以来看看点击了新增或者编辑按钮的方法ShowBox(...)
,接收一个参数QueryCategoryForAdminDto
让其默认值为null。
执行ShowBox()
方法,将弹窗打开,设置Open = true;
和初始化id的值id = 0;
。
通过参数是否null进行判断是新增还是更新,这样打开弹窗就搞定了,剩下的就交给弹窗来处理了。
因为新增和更新API需要还对应的输入参数EditCategoryInput
,去添加它不要忘了。
那么现在就只差按钮回调事件SubmitAsync()
了,主要是给输入参数进行赋值调用API,执行新增或者更新即可。
当参数为空时,直接return
什么都不执行。通过当前Id判断是新增还是更新操作,调用不同的方法PutAsJsonAsync
和PostAsJsonAsync
去请求API,同样返回到是HttpResponseMessage
对象,最后如果操作成功,重新请求一个数据,刷新分类列表,将弹窗关闭掉。
分类管理页面的全部代码如下:
点击查看代码
3|0弹窗组件
考虑到新增和更新数据的时候需要弹窗,这里就简单演示一下写一个小组件。
在 Shared 文件夹下新建一个Box.razor
。
在开始之前分析一下弹窗组件所需的元素,弹窗肯定有一个确认和取消按钮,右上角需要有一个关闭按钮,关闭按钮和取消按钮一个意思。他还需要一个打开或者关闭的状态,判断是否打开弹窗,还有就是弹窗内需要自定义展示内容。
确定按钮的文字可以自定义,所以差不多就需要3个参数,组件内容RenderFragment ChildContent
,是否打开弹窗bool Open
默认隐藏,按钮文字string ButtonText
默认值给"确定"。然后最重要的是确定按钮需要一个回调事件,EventCallback<MouseEventArgs> OnClickCallback
用于执行不同的事件。
右上角关闭和取消按钮直接在内部进行处理,执行Close()
方法,将参数Open
值设置为false即可。
对应的html如下。
4|0关于样式
下面是弹窗组件所需的样式代码,大家需要的自取,也可以直接去GitHub实时获取最新的样式文件。
好了,分类模块的功能都完成了,标签和友情链接的管理界面还会远吗?这两个模块的做法和分类是一样的,有兴趣的可以自己动手完成,今天到这吧,未完待续...
开源地址:https://github.com/Meowv/Blog/tree/blog_tutorial
__EOF__

本文链接:https://www.cnblogs.com/meowv/p/13124303.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构