[Mvp.Blazor] 动态路由与钩子函数

(Blazor组件的生命周期函数)

一直在学习也没有停下脚步,用着脑子还是挺好的,感觉可以更脚踏实地一下。

最近偶尔也继续看了看Blazor,毕竟我也开源了一个项目嘛,基本我正式开源的项目都会负责到底,所以该有的功能都要有的

(https://github.com/anjoy8/Blog.MVP.Blazor)

通过几天的学习,感觉愈发的感觉这门技术很棒,主要是很对我的脾气,用c#开发前端组件,生成交互式客户端 Web UI 的框架,一直是我连想象都不敢想的事情,不仅仅是它拥有组件继承、数据绑定、js交互、组件通讯等等前端比较亮眼的功能,最让我开心的就是他同样也有自己的生命周期,也就是文章的标题——钩子函数。要知道生命周期在前端框架开发中,还是有举足轻重的地位的。

那咱们暂时先不说这个钩子,先说下今天要干的事情,如何实现动态路由。

1、为什么要实现动态路由?

咱们先看看我之前是怎么做的,在blazor项目中,我们是这样设计的:

除了新增和删除外,就是展示页面,主要是按照一定的分类进行展示,所以呢,当时我为了图省事,每一个分类一个页面,每个页面发送同样的请求,所以基本的代码都一样:

每个页面定义各自的路由地址:

@page "/aspnetcore-abp-blazor/2020"
@page "/identityserver4/2020"
@page "/azure/2020"

纯手动硬编码操作,虽然创建了一个自定义组件,但是这种开发模式肯定是不可取的,不仅从软件开发上没有实现封装,而且在后期多个分类的时候,还要去创建页面,无法实现多态的,所以基于这个想法呢,我就觉得做个动态路由,其实在MVC开发中,也就是我们特别常见,也是玩腻的操作——把分类做个url参数来实现。

那具体如何实现呢,请继续往下看。

2、如何实现动态路由?

简单翻看官网,我们就看到了很清晰的介绍,然后快速的,大刀阔斧的开发了:

首先删掉那几个手写的分类页面,保留一个List.razor组件,Blogs文件夹主要就是实现动态展示,然后Post文件夹,用来进行修改和新增,更像是一个后台管理,而且是带权限那种(这里埋一个坑吧,目前还是没有研究透如何在Blazor.Server中集成Ids4,以后再看看)。

然后定义动态路由:

@page "/{type}/{year}"@code {[Parameter]public string type { get; set; } = "";[Parameter]public string year { get; set; } = "2020";private int num = 0;private MessageModel<List<BlogArticle>> _blogs;protected override async Task OnParametersSetAsync(){this._blogs = await Http.GetFromJsonAsync<MessageModel<List<BlogArticle>>>("http://apk.neters.club/api/Blog/GetBlogsByTypesForMVP?types=" + type);num = 0;}
}

核心的就是配置@page,然后还有定义两个必须是Public的变量参数,注意要增加特性[Parameter],不然就是普通的变量,从而无法url获取到指定的值。

看似一切很正常,也是和我想的一样,通过不同的url来访问,就能获取指定的内容,但是这个时候有一个小问题,如果在当前页面内,进行标签参数切换的话,就不行了。

但是加载后,跳转到首页,再点另一个分类,这样肯定是可以的。

那这是为什么呢?欸,这就引出了今天的重头戏——生命周期。

3、Blazor的生命周期

Blazor的生命周期与React组件的生命周期类似,分为三个阶段:初始化、运行中和销毁阶段,其相关方法有10个,包括设置参数前、初始化、设置参数之后、组件渲染后以及组件的销毁,但是这些方法有些是重复的,只不过是同步与异步的区别。

我因为有React的基础,所以看起来一目了然,当然如果你没学过React,但是学过Vue也行呀,毕竟我们Vue八个生命周期四个阶段都学过了,三个阶段的Blazor,学起来还不是分分钟的事儿。这就是文章开头的那张流程图。

具体的加载流程呢,我就不一一调试了,反正你打个断点,或者console输出一下,就能大概明白其中的过程是怎样的,这里说说那几个钩子函数:

(同步方法先于异步方法执行)

1设置参数前SetParametersAsync
2初始化OnInitialized/OnInitializedAsync
3设置参数后 OnParametersSet/OnParametersSetAsync
4组件渲染呈现后OnAfterRender/OnAfterRenderAsync
5判断是否渲染组件ShouldRender
6组件删除前Dispose
7通知组件渲染StateHasChanged

到了这里我们应该明白了,其实我们使用的是OnInitializedAsync钩子,是指我们的页面初始化完成后所执行的方法:

我们第一次访问的时候,肯定是执行一次初始化,但是实现了动态路由以后,在当前页面针对不同的标签进行切换的时候,其实已经不会再走初始化的钩子了。

那我就选择了一个其他的钩子,比如OnParametersSetAsync,设置参数后来实现数据源的获取,修改代码:

 //protected override async Task OnInitializedAsync()//{//    this._blogs = await Http.GetFromJsonAsync<MessageModel<List<BlogArticle>>>("http://apk.neters.club/api/Blog/GetBlogsByTypesForMVP?types=" + type);//    _blogs2 = _blogs.response;//}protected override async Task OnParametersSetAsync(){this._blogs = await Http.GetFromJsonAsync<MessageModel<List<BlogArticle>>>("http://apk.neters.club/api/Blog/GetBlogsByTypesForMVP?types=" + type);_blogs2 = _blogs.response;num = 0;}

这个时候,我们再点击标签切换的时候,就很随心所欲了。

经过测试已经没有问题了,你可以体验一下:
https://mvp.neters.club/

4、其他功能美化

文章编号

除了实现上边的动态路由以为,还简单的实现了文章编号的功能:

其实也是很简单的,而且也简单的写了一个填充的扩展——不足2位添0:

 /// <summary>/// /// </summary>/// <param name="thisValue"></param>/// <param name="fillDigits">填充位数</param>/// <returns></returns>public static string ObjToStringFill2(this int thisValue, int fillDigits = 2){if (thisValue >= 0 && thisValue < 10){return thisValue.ToString().PadLeft(fillDigits, '0');}return thisValue.ObjToString();}

搜索功能

之前我们说过Blazor是支持双向绑定的,那我们就基于这个功能,实现搜索功能:

好啦,今天的内容就暂时到这里了,通过很小的功能,相信你应该对Blazor的钩子函数,动态路由,数据绑定有了一定的认识和了解了吧。

下次再见咯。

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

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

相关文章

算法-找出最近点对问题

最近点对问题 找出平面上一对距离最短的点&#xff0c;时间复杂度 O&#xff08;nlgn&#xff09; using System; using System.Collections.Generic;namespace dataLearn {struct Coordinate{public float x;public float y;public Coordinate(float x,float y){this.x x;t…

算法-二分搜索-找出最大值和最小值

二分搜索问题 找出最大值和最小值 时间复杂度O&#xff08;n&#xff09; using System; using System.Collections.Generic;namespace dataLearn {class Program{static void Main(string[] args){List<int> list new List<int> { 10, 3, 6, 4, 7, 1, 9, 2 };v…

Java面向对象编程(高级)

面向对象编程(高级) 类变量和类方法 01: package ChildDemo;public class Child {private String name;public static int cnt 0;public Child(String name){this.name name;}public void join(){System.out.println(name "join the game");} }//package ChildDe…

.NET Core + Kubernetes:Volume

和 Docker 类似&#xff0c;Kubernetes 中也提供了 Volume 来实现数据卷挂载&#xff0c;但 Kubernetes 中 Volume 是基于 Pod&#xff0c;而不是容器&#xff0c;它可被 Pod 中多个容器共享&#xff0c;另外 Kubernetes 中提供比较丰富的 Volume 类型[1]&#xff0c;如&#…

算法-二分搜索-找出最大值和次大值

二分搜索 <2>找出最大值和第二大值 时间复杂度O&#xff08;n) class Program {static void Main(string[] args){List<int> list new List<int> { 10, 3, 6, 4, 7, 1, 9, 2 };var v getMax(list, 0, list.Count - 1);}static (int, int) getMax(List<…

WPF中的Data Binding调试指南

点击蓝字“大白技术控”关注我哟加个“星标★”&#xff0c;每日良时&#xff0c;好文必达&#xff01;WPF中的Data Binding如何Debug?大家平时做WPF开发&#xff0c;相信用Visual studio的小伙伴比较多。XAML代码曾经在某些特殊版本的Visual Studio中是可以加断点进行调试的&…

算法-连续项的最大和问题(最大子数组问题)三种不同解法

连续项的最大和问题 &#xff08;1&#xff09;暴力求解 时间复杂度 O&#xff08;n^2&#xff09; &#xff08;2&#xff09;分治求解 时间复杂度 O&#xff08;nlogn&#xff09; &#xff08;3&#xff09; 线性求解 时间复杂度 O&#xff08;n&#xff09; C#代码 usin…

.NET 5 尝鲜 - 开源项目TerminalMACS WPF管理端支持.NET 5

点击上方“Dotnet9”添加关注哦聊天界面设计TerminalMACS一个使用 Prism 作为模块化框架、基于多个开源控件库作为UI控件选择、集成开源 UI 界面设计的 .NET 5 WPF 客户端项目。项目名称&#xff1a;TerminalMACS WPF管理端项目开源地址&#xff1a;Github&#xff1a;https://…

算法-排序-插入排序

插入排序 特点&#xff1a;原址排序&#xff0c;比较排序&#xff0c;&#xff08;最坏的情况&#xff09;时间复杂度O&#xff08;n^2&#xff09; #include <iostream>void insertion_sort(int *arr,int start,int end) {for (int i start1; i < end1; i) {int k…

MongoDB via Dotnet Core数据映射详解

用好数据映射&#xff0c;MongoDB via Dotnet Core开发变会成一件超级快乐的事。一、前言MongoDB这几年已经成为NoSQL的头部数据库。由于MongoDB free schema的特性&#xff0c;使得它在互联网应用方面优于常规数据库&#xff0c;成为了相当一部分大厂的主数据选择&#xff1b;…

算法-排序-归并排序

归并排序 特点&#xff1a;非原址排序&#xff0c;比较排序&#xff0c;时间复杂度O&#xff08;nlgn&#xff09; 稳定 // // Created by 许加权 on 2021/6/18. //#include <iostream> void merge_sort(int *arr,int start,int end) {if(start < end){int middle …

FreeSql.Generator命令行代码生成器是如何实现的

目录FreeSql介绍FreeSql.GeneratorRazorEngine.NetCore源码解析FreeSql.ToolsFreeSqlFreeSql 是功能强大的对象关系映射技术(O/RM)&#xff0c;支持 .NETCore 2.1 或 .NETFramework 4.0 或 Xamarin。有一个强大的ORM&#xff0c;也方便我们开发一个代码生成器。一般情况下&…

算法-排序-选择排序

选择排序 特点&#xff1a;原址排序&#xff0c;比较排序&#xff0c;时间复杂度O&#xff08;n^2&#xff09; // // Created by 许加权 on 2021/6/19. //#include <iostream>void selection_sort(int *arr,int start,int end) {for (int i start 1; i < end1; i…

.Net Core Configuration Etcd数据源

前言.Net Core为我们提供了一套强大的Configuration配置系统&#xff0c;使用简单扩展性强。通过这套配置系统我们可以将Json、Xml、Ini等数据源加载到程序中,也可以自己扩展其他形式的存储源。今天我们要做的就是通过自定义的方式为其扩展Etcd数据源操作。何为Etdc在使用etcd之…

算法-二分查找

二分查找 特点&#xff1a; T(n) T(n/2 - 1) c 时间复杂度O&#xff08;lgn) 前提&#xff1a;需要已排序的集合 int binary_search(int *arr,int start,int end,int key) {if(start<end){int middle (startend)/2;if(arr[middle] key) return middle;if(key<arr[m…

Java IDEA断点调试

断点调试(debug) 断点调试应用案例 01&#xff1a; package Assign;public class Debug01 {public static void main(String[] args) {int sum 0;for (int i 0;i<5;i){sumi;System.out.println(i);System.out.println(sum);}System.out.println("continue");} …

.NET Core请求控制器Action方法正确匹配,但为何404?

【导读】提前预祝各位端午节快乐。有时候我们会发现方法名称都正确匹配&#xff0c;但就是找不到对应请求接口&#xff0c;所以本文我们来深入了解下何时会出现接口请求404的情况。匹配控制器Action方法&#xff08;404&#xff09;首先我们创建一个web api应用程序&#xff0c…

布斯乘法以及带符号数的运算

乘法理解 对于最熟悉的十进制乘法很最基本的运算原理就是一个乘数乘以另一个乘数的个位、十位、百位数字然后求和。比如 放到二进制来看其实它也是这样的&#xff0c;多位数的乘法就是一个乘数乘上另一个乘数的各位求和。那么&#xff1a; 布斯算法及原理 原理 已经知道两…

算法-排序-冒泡排序

冒泡排序 特点&#xff1a;原址排序&#xff0c;比较排序 时间复杂度O&#xff08;n^2) void bubble_sort(int *arr,int start,int end) {for (int i start; i < end; i) {for (int j end; j >i ; j--) {if(arr[j-1]>arr[j]){int temp arr[j];arr[j] arr[j-1];a…

C++重载输出操作符<<,为什么要返回引用

针对&#xff1a;ostream & operator <<(ostream & os, const ClassType &object) 说明几点&#xff1a; 1.第一个形参为对ostream对象的引用&#xff0c;在该对象上将产生输出&#xff0c;ostream为非const&#xff0c;因为写入到流会改变流的状态&#x…