做网站应该先从什么地方开始,建设工程信息网一体化平台,广告类的网站,网站开发技术选型系列文章使用 abp cli 搭建项目给项目瘦身#xff0c;让它跑起来完善与美化#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API#xff0c;包装返回模型再说Swagger#xff0c;分组、描述、小绿锁接入GitHub#xff0c;用JWT保护你的API异常处理和… 系列文章使用 abp cli 搭建项目给项目瘦身让它跑起来完善与美化Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API包装返回模型再说Swagger分组、描述、小绿锁接入GitHub用JWT保护你的API异常处理和日志记录使用Redis缓存数据集成Hangfire实现定时任务处理用AutoMapper搞定对象映射定时任务最佳实战一定时任务最佳实战二定时任务最佳实战三博客接口实战篇一博客接口实战篇二博客接口实战篇三博客接口实战篇四博客接口实战篇五Blazor实战系列一Blazor实战系列二Blazor实战系列三上一篇完成了博客的分页查询文章列表页面的数据绑定和分页功能本篇将继续完成剩下的几个页面。在开始主题之前重新解决上一篇的最后一个问题当点击了头部组件的/posts链接时直接强制刷新了页面经过查看文档和实践有了更好的解决方案。先将头部组件Header.razor中的NavLink恢复成NavLink classmenu-item hrefpostsPosts/NavLink不需要点击事件了。然后在Posts.razor中添加生命周期函数OnParametersSetAsync()在初始化完成后执行。/// summary
/// 初始化完成后执行
/// /summary
/// returns/returns
protected override async Task OnParametersSetAsync()
{if (!page.HasValue){page 1;await RenderPage(page);}
}
判断当前page参数是否有值有值的话说明请求肯定是来自于翻页当page没有值的时候就说明是头部的菜单点进来的。那么此时给page赋值为1调用API加载数据即可。分类列表Categories.razor是分类列表页面上篇文章已经实现了从API获取数据的方法所以这里就很简单了指定接受类型然后在生命周期初始化OnInitializedAsync()中去获取数据。code{/// summary/// categories/// /summaryprivate ServiceResultIEnumerableQueryCategoryDto categories;/// summary/// 初始化/// /summaryprotected override async Task OnInitializedAsync(){// 获取数据categories await Http.GetFromJsonAsyncServiceResultIEnumerableQueryCategoryDto($/blog/categories);}
}
当获取到数据的时候进行绑定没有数据的时候还是显示加载中的组件Loading /让他转圈圈。if (categories null)
{Loading /
}
else
{div classcontainerdiv classpost-wrap categoriesh2 classpost-title-nbsp;Categoriesnbsp;-/h2div classcategories-cardif (categories.Success categories.Result.Any()){foreach (var item in categories.Result){div classcard-itemdiv classcategoriesa href/category/item.DisplayName/h3i classiconfont iconcode stylepadding-right:3px/iitem.CategoryName/h3small(item.Count)/small/a/div/div}}else{ErrorTip /}/div/div/div
}
直接循环返回的数据列表categories.Result绑定数据就好当获取失败或者没有返回数据的时候显示错误提示组件ErrorTip /标签列表Categories.razor是标签列表页面和分类列表HTML结构差不多一样的除了返回类型和接口地址不一样将上面代码复制过来改改即可。code{/// summary/// tags/// /summaryprivate ServiceResultIEnumerableQueryTagDto tags;/// summary/// 初始化/// /summaryprotected override async Task OnInitializedAsync(){// 获取数据tags await Http.GetFromJsonAsyncServiceResultIEnumerableQueryTagDto($/blog/tags);}
}
if (tags null)
{Loading /
}
else
{div classcontainerdiv classpost-wrap tagsh2 classpost-title-nbsp;Tagsnbsp;-/h2div classtag-cloud-tagsif (tags.Success tags.Result.Any()){foreach (var item in tags.Result){a href/tag/item.DisplayName/item.TagNamesmall(item.Count)/small/a}}else{ErrorTip /}/div/div/div
}
友链列表FriendLinks.razor是友情链接列表页面实现方式和上面两个套路一模一样。code {/// summary/// friendlinks/// /summaryprivate ServiceResultIEnumerableFriendLinkDto friendlinks;/// summary/// 初始化/// /summaryprotected override async Task OnInitializedAsync(){// 获取数据friendlinks await Http.GetFromJsonAsyncServiceResultIEnumerableFriendLinkDto($/blog/friendlinks);}
}
if (friendlinks null)
{Loading /
}
else
{div classcontainerdiv classpost-wrap categoriesh2 classpost-title-nbsp;FriendLinksnbsp;-/h2div classcategories-cardif (friendlinks.Success friendlinks.Result.Any()){foreach (var item in friendlinks.Result){div classcard-itemdiv classcategoriesa target_blank hrefitem.LinkUrlh3item.Title/h3/a/div/div}}else{ErrorTip /}/div/div/div
}
文章列表(分类)Posts.Category.razor是根据分类查询文章列表页面他接受一个参数name我们要根据name去API查询数据然后绑定页面即可。这里的参数name实际上就是从标签列表传递过来的DisplayName的值它是一个比较友好的名称我们还要通过这个值去查询真正的分类名称进行展示所以这里需要调用两个API这点在设计API的时候没有考虑好我们其实可以将这两个API合并变成一个后续再进行优化吧这里就请求两次。添加两个接收参数分类名称和返回的文章列表数据。/// summary
/// 分类名称
/// /summary
private string categoryName;/// summary
/// 文章列表数据
/// /summary
private ServiceResultIEnumerableQueryPostDto posts;
然后在OnInitializedAsync()初始化方法中调用API获取数据赋值给变量。/// summary
/// 初始化
/// /summary
protected override async Task OnInitializedAsync()
{// TODO:获取数据,可以在API中合并这两个请求。var category await Http.GetFromJsonAsyncServiceResultstring($/blog/category?name{name});posts await Http.GetFromJsonAsyncServiceResultIEnumerableQueryPostDto($/blog/posts/category?name{name});if (category.Success){categoryName category.Result;}
}
有了数据直接在页面上进行循环绑定。if (posts null)
{Loading /
}
else
{div classcontainerdiv classpost-wrap tagsif (categoryName ! null){h2 classpost-title-nbsp;Categorynbsp;·nbsp;categoryNamenbsp;-/h2}/divdiv classpost-wrap archiveif (posts.Success posts.Result.Any()){foreach (var item in posts.Result){h3item.Year/h3foreach (var post in item.Posts){article classarchive-itemNavLink href(/postpost.Url)post.Title/NavLinkspan classarchive-item-datepost.CreationTime/span/article}}}else{ErrorTip /}/div/div
}
文章列表(标签)Posts.Tag.razor是根据标签查询文章列表这个和分类查询文章列表实现方式一样直接上代码。code {/// summary/// 标签名称参数/// /summary[Parameter]public string name { get; set; }/// summary/// 标签名称/// /summaryprivate string tagName;/// summary/// 文章列表数据/// /summaryprivate ServiceResultIEnumerableQueryPostDto posts;/// summary/// 初始化/// /summaryprotected override async Task OnInitializedAsync(){// TODO:获取数据,可以在API中合并这两个请求。var tag await Http.GetFromJsonAsyncServiceResultstring($/blog/tag?name{name});posts await Http.GetFromJsonAsyncServiceResultIEnumerableQueryPostDto($/blog/posts/tag?name{name});if (tag.Success){tagName tag.Result;}}
}
if (posts null)
{Loading /
}
else
{div classcontainerdiv classpost-wrap tagsif (tagName ! null){h2 classpost-title-nbsp;Tagnbsp;·nbsp;tagNamenbsp;-/h2}/divdiv classpost-wrap archiveif (posts.Success posts.Result.Any()){foreach (var item in posts.Result){h3item.Year/h3foreach (var post in item.Posts){article classarchive-itemNavLink href(/postpost.Url)post.Title/NavLinkspan classarchive-item-datepost.CreationTime/span/article}}}else{ErrorTip /}/div/div
}
以上完成了以上几个页面的数据绑定页面之间的跳转已经关联起来了然后还剩下文章详情页大家可以先自己动手完成它今天就到这里未完待续...开源地址https://github.com/Meowv/Blog/tree/blog_tutorial