基于 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 开发博客项目 - 终结篇之发布项目
上一篇完成了标签模块和友情链接模块的所有功能,本篇来继续完成博客最后的模块,文章的管理。
2|0文章列表 & 删除
先将分页查询的列表给整出来,这块和首页的分页列表是类似的,就是多了个Id字段。
先添加两条路由规则。
新建返回数据默认QueryPostForAdminDto.cs
。
然后添加所需的参数:当前页码、限制条数、总页码、文章列表返回数据模型。
然后在初始化函数OnInitializedAsync()
中调用API获取文章数据.
在初始化中判断page参数,如果没有值给他设置一个默认值1。RenderPage(int? page)
方法是调用API返回数据,并计算出总页码值。
最后在页面上进行数据绑定。
HTML内容放在组件AdminLayout
中,当 posts 没加载完数据的时候显示加载组件<Loading />
。
在页面上循环遍历文章数据和翻页页码,每篇文章标题前面添加两个按钮删除和编辑,同时单独加了一个新增文章的按钮。
删除文章调用DeleteAsync(int id)
方法,需要传递参数,当前文章的id。
新增和编辑按钮都跳转到"/admin/post"页面,当编辑的时候将id也传过去即可,路由规则为:"/admin/post/{id}"。
删除文章``方法如下:
删除之前进行二次确认,避免误删,当确认删除之后调用删除文章API,最后重新渲染数据即可。
3|0新增 & 更新文章
完成了后台文章列表的查询和删除,现在整个博客模块功能就差新增和更新文章了,胜利就在前方,冲啊。
这块的开发工作耗费了我太多时间,因为想使用 markdown 来写文章,找了一圈下来没有一个合适的组件,所以退而求次只能选择现有的markdown编辑器来实现了。
我这里选择了开源的编辑器Editor.md
,有需要的可以去 Github 自己下载,https://github.com/pandao/editor.md 。
将下载的资源包解压放在 wwwroot 文件夹下,默认是比较大的,而且还有很多示例文件,我已经将其精简了一番,可以去我 Github 下载使用。
先来看下最终的成品效果吧。
是不是感觉还可以,废话不多说,接下里告诉大家如何实现。
在 Admin 文件夹下添加post.razor
组件,设置路由,并且引用一个样式文件,在页面中引用样式文件好像不太符合标准,不过无所谓了,这个后台就自己用,而且还就这一个页面用得到。
把具体HTML内容放在组件AdminLayout
中。
因为新增和编辑放在同一个页面上,所以当id参数不为空的时候需要添加一个id参数,同时默认一进来就让页面显示加载中的组件,当页面和数据加载完成后在显示具体的内容,所以在指定一个布尔类型的是否加载参数isLoading
。
我们的编辑器主要依赖JavaScript实现的,所以这里不可避免要使用到JavaScript了。
在app.js
中添加几个全局函数。
renderEditor
主要实现了动态加载JavaScript代码,将markdown编辑器渲染出来。这里不多说,都是Editor.md
示例里面的代码。
为了兼容暗黑色主题,这里还加了一个切换编辑器主题的JavaScript方法,switchEditorTheme
。
_shoowBox
就厉害了,这个方法是调用的.NET组件中的方法,前面我们用过了在Blazor中调用JavaScript,这里演示了JavaScript中调用Blazor中的组件方法。
现在将所需的几个参数都添加到代码中。
大家看看注释就知道参数是做什么的了。
现在我们在初始化函数中将所需的数据通过API获取到。
action是一个异步的委托,在初始化中执行了ChangeOpenStatus
方法,这个方法等会说,然后获取localStorage
中token的值。
通过参数Id是否有值来判断当前是新增文章还是更新文章,如果有值就是更新文章,这时候需要根据id去将文章的数据拿到赋值给PostForAdminDto
对象展示在页面上,如果没有可以添加几个默认值给PostForAdminDto
对象。
因为文章需要分类和标签的数据,同时这里将分类的数据也查出来,标签默认是List列表,将其转换成字符串类型。
但完成上面操作后,调用JavaScript方法renderEditor
渲染渲染编辑器,最后关闭加载,显示页面。
现在来看看页面。
添加了四个input框,分别用来绑定标题、作者、URL、时间,<div id="editor"></div>
中为编辑器所需。
然后我这里还是把之前的弹窗组件搞出来了,执行逻辑不介绍了,在弹窗组件中自定义显示分类和标签的内容,将获取到的分类和标签绑定到具体位置。
每个分类都是一个radio标签,并且对应一个点击事件,点哪个就把当前分类的Id赋值给PostForAdminDto
对象。
所有的input框都使用@bind
和@bind:event
绑定数据和获取数据。
Box
弹窗组件这里自定义了按钮文字,ButtonText="发布"
。
现在可以来看看ChangeOpenStatus
方法了,这个是改变当前弹窗状态的一个方法。为什么需要这个方法呢?
因为在Blazor中JavaScript想要调用组件内的方法,方法必须是静态的,那么只能通过这种方式去实现了,在静态方法是不能够直接改变弹窗的状态值的。
其实也可以不用这么麻烦,因为我在编辑器上自定义了一个按钮,为了好看一些所以只能曲折一点,嫌麻烦的可以直接在页面上搞个按钮执行保存数据逻辑也是一样的。
使用JSInvokable
Attribute需要在_Imports.razor
中添加命名空间@using Microsoft.JSInterop
。
ChangeOpenStatus
中获取到文章内容:HTML和markdown,赋值给PostForAdminDto
对象,要先进行判断页面上的几个参数是否有值,没值的话给出提示执行Alert()
方法,最后使用StateHasChanged()
通知组件其状态已更改。
Alert
方法就是调用原生的JavaScriptalert
方法,给出一个提示。
ShowBox
就是暴漏给JavaScript的方法,使用DotNet.invokeMethodAsync('Meowv.Blog.BlazorApp', 'showbox');
进行调用。
那么现在一切都正常进行的情况下,点击编辑器上自定义的保存按钮,页面上值不为空的情况下就会弹出我们的弹窗组件Box
。
最后在弹窗组件的回调方法中执行新增文章还是更新文章。
打开弹窗后执行回调事件之前还是要判断值是否为空,为空的情况下还是给出alert
提示,此时将tags标签还是转换成List列表,根据Id是否有值去执行新增数据或者更新数据,最终成功后跳转到文章列表页。
本片到这里就结束了,主要攻克了在Blazor中使用Markdown编辑器实现新增和更新文章,这个系列差不多就快结束了,预计还有2篇的样子,感谢各位的支持。
开源地址:https://github.com/Meowv/Blog/tree/blog_tutorial
__EOF__

本文链接:https://www.cnblogs.com/meowv/p/13124967.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语句:使用策略模式优化代码结构