Web应用程序的可以通过URL将多个页面串联起来,并且可以互相跳转。Web应用主要是使用a标签或者是服务端redirect来跳转。而现在流行的单页应用程序 (SPA) ,则通过路由(Router)来实现跳转,如Vue 、React等。

提示

MAUI的路由与Blazor路由有很大区别。

MAUI Blazor的路由

在.NET MAUI Blazor应用中,路由是遵循Blazor的路由规则。也是通过路由组件(Router)实现的,打开Main.razor可以看到:

<Router AppAssembly="@typeof(Main).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
<!--设置容器-->
<AntContainer />

Router 有两个子节点FoundNotFound

  • Found节点包含一个RouteView的定义,如果找到了路由定义就通过RouteView来呈现对应的页面,同时为所有页面指定默认的模板。
  • NotFound节点包含一个LayoutView的定义,如果没找到路由定义则呈现一个特定的页面,这里使用的默认模板是MainLayout,也可以自己实现一个。

定义MAUI Blazor路由

在MAUI Blazor中,路由的定义使用@page指令进行指定。在创建Blazor组件的时候,必须包含@page '路径"

MAUI路由与MAUI Blazor路由有很大区别

MAUI创建路由是根据Route属性或者通过 Routing.RegisterRoute显式的注册路由。

MAUI Blazor 则是在组件上,使用@page指令指定。

Visual Studio 2022编译器在编译带有 @page 指令的 Razor 组件 (.razor) 时,将为组件类提供一个 RouteAttribute 来指定组件的路由。

当应用程序启动时,应用程序将扫描由Router组件中AppAssembly属性指定的程序集,收集程序集中具有 RouteAttribute 的Blazor组件的路由信息。

在应用程序运行时,RouteView 组件:

  • 从 Router 接收 RouteData 以及所有路由参数。
  • 使用指定的组件的布局来呈现该组件,包括任何后续嵌套布局。

提示

Router 不与查询字符串值交互。

匹配到路由时

我们在上次代码的基础上,增加一个页面。在Pages目录下,新建一个Blazor组件:pdf.razor。创建完成后,默认代码是这样的:

<h3>pdf</h3>

@code {

}

我们使用@page指令指定路由为pdf。并写上几个大字。

@page "/PDF"

<Title Level="1">使用iTextSharp生成PDF文件</Title>

然后打开MainLayout.razor,给菜单增加一个MenuDataItem

new MenuDataItem
{
Path = "/PDF",
Name = "PDF",
Key = "PDF",
Icon = "file-pdf"
}

注意:

Blazor组件必须是大写字母开头,如果使用小写字母开头,编译的时候,会报一个错:

Component 'xxx' starts with a lowercase character. Component names cannot start with a lowercase character

xxx是组件的名字。

看下运行的效果:

未匹配到路由时

如果未匹配到路由,则会呈现上面的NotFound节点定义的内容。先把NotFound节点的内容稍微改造一下!

<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<div style="text-align:center"><Icon Type="close-circle" Theme="twotone" TwotoneColor="#ff0000" Height="5em" Width="5em" /></div>
<div style="margin-top:15px;text-align:center"><Title Level="3">页面走失!请确认输入的URL是否正确!</Title></div>
</LayoutView>
</NotFound>

MainLayout.razor中,增加一个MenuDataItem,指向一个不存在的页面:

new MenuDataItem
{
Path = "/DataList",
Name = "DataList",
Key = "DataList",
Icon = "appstore"
}

看下运行效果:

路由跳转

很多场景中,除了点击左侧的菜单跳转外,在页面中也需要进行跳转,Blazor支持的跳转除了HTML标记<a></a>外,还有个NavigationManager类。

NavigationManager类在Microsoft.AspNetCore.Components命名空间下。

改造下Index.razor

@page "/"
@inject NavigationManager navigationManager
<Title Level="1">Hello,DotNet宝藏库</Title>
<div style="margin-top:15px;"><Text Type="success">欢迎关注我的公众号!</Text></div>
<Divider />
<div style="margin-top:20px;"><a href="/Counter">使用a 标记跳转</a></div>
<div style="margin-top:20px;">
<Button Danger Type="@ButtonType.Primary" OnClick="()=>DirectToCounter()">使用NavigationManager跳转</Button>
</div>
@code
{
private void DirectToCounter()
{
navigationManager.NavigateTo("/Counter");
}
}

这时,不论是点击链接还是点击按钮,都可以跳转到响应页面!

路由参数

路由的过程当中经常需要进行参数传递,以方便我们跳转到的新页面后进行一些操作。

Blazor传参分为两种情况:path传参以及QueryString传参。我们分别介绍下这两种传参的方法。

path传参

path传参就是把参数组合在URL路径里,接收参数的页面需要在@page以相同的名称填充参数。并添加Parameter特性对参数进行修饰。

先改造下Counter.razor

@page "/counter"
@page "/counter/{initNum}" <Title Level="2">Counter</Title>
<Divider />
<p role="status">Current count: @currentCount</p> <Button @onclick="IncrementCount" Type="primary">AntDesign 按钮</Button>
@code {
[Parameter]
public string initNum{ get; set; } private int currentCount = 0; protected override void OnParametersSet()
{
if (!int.TryParse(initNum, out int num))
{
currentCount = 0;
}else
{
currentCount = num;
}
}
private void IncrementCount()
{
currentCount++;
} }

代码中,增加了一个@page "/counter/{initNum}"{initNum}就是参数。

注意参数是不区分大小写的,但是为了更规范,建议URL全部用小写,c#代码则使用驼峰式命名。

还有Blazor并不支持可选参数,所以如果这个例子里面的initNum是可有可无的,则需要使用@page指令来定义两条路由,一条包含initNum,另一条不包含。

OnParametersSetOnParametersSetAsync中,我们把initNum赋值给currentCount

修改下Index.razor中的DirectToCounter方法:

 private void DirectToCounter()
{
navigationManager.NavigateTo("/Counter/10");
}

运行起来,当点击使用NavigationManager跳转按钮后,Counter.razor中的currentCount为10。

QueryString 传参

除了把参数直接拼接在URL路径(path)里,另一种常用的传递参数的方法是,将参数做为QueryString传递给跳转页面,比如“/Counter?initNum=3”。我们可从 NavigationManager.Uri 属性中获取请求的查询字符串。

Index.razor里的

<a href="/Counter">使用a 标记跳转</a>改为<a href="/Counter?initNum=5">使用a 标记跳转</a>

修改Counter.razor,先引入NavigationManager

@page "/counter"
@inject NavigationManager navigationManager

OnParametersSet内获取参数

	protected override void OnParametersSet()
{
//if (!int.TryParse(initNum, out int num))
//{
// currentCount = 0;
//}else
//{
// currentCount = num;
//}
var query = new Uri(navigationManager.Uri).Query;
Console.WriteLine(query);
}

断点后,可以看到,从Index.razor点击链接跳转到Counter.razor后,获取到了参数:



这里有个问题,获取到的参数不是键值对,而是一串字符串。与我们的期望不同。不过还好,我们可以通过QueryHelpers.ParseQuery来获取到键值对信息。

1、添加依赖:

PM> NuGet\Install-Package Microsoft.AspNetCore.WebUtilities -Version 2.2.0

2、解析参数

var queryDic = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);



可以获取到参数值了。把代码补充完整:

protected override void OnParametersSet()
{
//if (!int.TryParse(initNum, out int num))
//{
// currentCount = 0;
//}else
//{
// currentCount = num;
//}
var query = new Uri(navigationManager.Uri).Query;
var queryDic = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);
if (queryDic.ContainsKey("initNum"))
{
var count_str = queryDic["initNum"].ToString() ?? "";
if (!int.TryParse(count_str, out int num))
{
currentCount = 0;
}
else
{
currentCount = num;
}
}
else
{
currentCount = 0;
} }

运行一下看看效果

路由约束

路由约束强制在路由段和组件之间进行类型匹配。像刚才例子中的initNum,我们可以写成@page "/counter/{initNum:int}",路由约束不适用于查询字符串,也就是QueryString传递的参数。Blazor支持以下几种约束类型:

  • bool
  • datetime
  • decimal
  • double
  • float
  • guid
  • int
  • long

总结

暂无,下次再会!

欢迎大家关注我的微信公众号,一起进步,一起成长

学习.NET MAUI Blazor(四)、路由的更多相关文章

  1. 我的MYSQL学习心得(十四) 备份和恢复

    我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...

  2. 【Unity Shaders】学习笔记——SurfaceShader(四)用纹理改善漫反射

    [Unity Shaders]学习笔记——SurfaceShader(四)用纹理改善漫反射 转载请注明出处:http://www.cnblogs.com/-867259206/p/5603368.ht ...

  3. OpenGL学习之路(四)

    1 引子 上次读书笔记主要是学习了应用三维坐标变换矩阵对二维的图形进行变换,并附带介绍了GLSL语言的编译.链接相关的知识,之后介绍了GLSL中变量的修饰符,着重介绍了uniform修饰符,来向着色器 ...

  4. python学习笔记--Django入门四 管理站点--二

    接上一节  python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...

  5. VSTO学习笔记(十四)Excel数据透视表与PowerPivot

    原文:VSTO学习笔记(十四)Excel数据透视表与PowerPivot 近期公司内部在做一种通用查询报表,方便人力资源分析.统计数据.由于之前公司系统中有一个类似的查询使用Excel数据透视表完成的 ...

  6. Linux学习总结(十四)—— 查看CPU信息

    文章首发于[博客园-陈树义],点击跳转到原文Linux学习总结(十四)-- 查看CPU信息. Linux学习总结(十四)-- 查看CPU信息 商用服务器CPU最常用的是 Intel Xeon 系列,该 ...

  7. Python学习笔记(十四)

    Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...

  8. angular学习笔记(5)- 路由

    angular1学习笔记(5)- 路由 需要前端路由的原因: 1.ajax请求不会留下History记录 2.用户无法通过URL进入应用中的指定页面(保存书签.链接分享给朋友) 3.ajax对SEO是 ...

  9. 【平差软件学习---科傻】四、科傻二等水准平差(参数设置和in1文件讲解)

    [平差软件学习---科傻]四.科傻二等水准平差(参数设置和in1文件讲解) 这个算是最后一集了,也可能不是如果我想到不足的地方我会在补上一集视频,或者是文章页.总感觉自己操作的很熟练,到自己真正讲的时 ...

  10. golang学习笔记6 beego项目路由设置

    golang学习笔记5 beego项目路由设置 前面我们已经创建了 beego 项目,而且我们也看到它已经运行起来了,那么是如何运行起来的呢?让我们从入口文件先分析起来吧: package main ...

随机推荐

  1. C语言小白刷题

    1.有n个评委,他们给出score个分数,请用代码写出平均值,ave代表平均值 2022-10-15 13:17:10 int main() { int n, i =1, score, sum = 0 ...

  2. 一文理解Cookie、Session

    一文理解Cookie.Session 1.什么是会话 用户打开浏览器,点击多个超链接,访问服务器的多个web资源,然后关闭浏览器,整个过程就称为一个会话: HTTP 是无状态,有会话的 HTTP 是无 ...

  3. 二、.Net Core搭建Ocelot

    上一篇文章介绍了Ocelot的基本概念:https://www.cnblogs.com/yangleiyu/p/15043762.html 本文介绍在.net core中如何使用ocelot. Oce ...

  4. Codeforces Round #812 (Div. 2) D. Tournament Countdown(交互题)

    记录一下第一次写交互题 题目大意:一共有1<<n个人参加一场竞标赛,需要你通过比较两人的胜场来判断谁晋级,最终获得第一名 最多1/3*2^(n+1)次询问,每次询问query(a,b),如 ...

  5. promise 的串行执行

    function pri (num) {   return new Promise((resolve,reject) => {     console.log('开始'+num)     res ...

  6. 浅谈MYSQL的索引以及它的数据结构

    什么是索引 mysql的数据是持久化到磁盘的,写SQL查询数据也就是在磁盘的某个位置查找符合条件的数据,但是磁盘IO比起内存效率是极慢的,特别是数据量大的时候,这时候就需要引入索引来提高查询效率: 在 ...

  7. Halocn双目相机标定

    [Halcon]Halcon双目标定 相机标定(4)---基于halcon的双目立体视觉标定 双目立体视觉:四(双目标定matlab,图像校正,图像匹配,计算视差,disparity详解,) 双目测距 ...

  8. swap,传参实质

    void swap(int a,int b){ int s=a; a=b; b=s; } int main(){ int x=1,y=2; swap(x,y); } 上面的函数并不能实现交换,因为传参 ...

  9. tp6 requset获取参数的方式

    第一种:获取全部参数的值 request()->param() 1 第二种:获取排除某些字段的值,即获取其他值 request()->except(['serverToken','logi ...

  10. VR技术名词解释

    视觉相关技术 分辨率 分辨率(resolution)就是屏幕图像的精密度,是指显示器所能显示的像素的多少.由于屏幕上的点.线和面都是由像素组成的,显示器可显示的像素越多,画面就越精细,同样的屏幕区域内 ...