翼度科技»论坛 编程开发 .net 查看内容

学习.NET MAUI Blazor(四)、路由

7

主题

7

帖子

21

积分

新手上路

Rank: 1

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

目录

MAUI Blazor的路由

在.NET MAUI Blazor应用中,路由是遵循Blazor的路由规则。也是通过路由组件(Router)实现的,打开Main.razor可以看到:
  1. <Router AppAssembly="@typeof(Main).Assembly">
  2.     <Found Context="routeData">
  3.         <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
  4.         <FocusOnNavigate RouteData="@routeData" Selector="h1" />
  5.     </Found>
  6.     <NotFound>
  7.         <LayoutView Layout="@typeof(MainLayout)">
  8.             <p role="alert">Sorry, there's nothing at this address.</p>
  9.         </LayoutView>
  10.     </NotFound>
  11. </Router>
  12. <AntContainer />
复制代码
在Router 有两个子节点Found与NotFound。

  • 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。创建完成后,默认代码是这样的:
  1. <h3>pdf</h3>
  2. @code {
  3. }
复制代码
我们使用@page指令指定路由为pdf。并写上几个大字。
  1. @page "/PDF"
  2. <Title Level="1">使用iTextSharp生成PDF文件</Title>
复制代码
然后打开MainLayout.razor,给菜单增加一个MenuDataItem。
  1. new MenuDataItem
  2. {
  3.         Path = "/PDF",
  4.         Name = "PDF",
  5.         Key = "PDF",
  6.         Icon = "file-pdf"
  7. }
复制代码
注意:
Blazor组件必须是大写字母开头,如果使用小写字母开头,编译的时候,会报一个错:
Component 'xxx' starts with a lowercase character. Component names cannot start with a lowercase character
xxx是组件的名字。
看下运行的效果:

未匹配到路由时

如果未匹配到路由,则会呈现上面的NotFound节点定义的内容。先把NotFound节点的内容稍微改造一下!
  1. <NotFound>
  2.         <LayoutView Layout="@typeof(MainLayout)">
  3.             <Icon Type="close-circle" Theme="twotone" TwotoneColor="#ff0000" Height="5em" Width="5em" />
  4.             <Title Level="3">页面走失!请确认输入的URL是否正确!</Title>
  5.         </LayoutView>
  6.     </NotFound>
复制代码
在MainLayout.razor中,增加一个MenuDataItem,指向一个不存在的页面:
  1. new MenuDataItem
  2. {
  3.         Path = "/DataList",
  4.         Name = "DataList",
  5.         Key = "DataList",
  6.         Icon = "appstore"
  7. }
复制代码
看下运行效果:

路由跳转

很多场景中,除了点击左侧的菜单跳转外,在页面中也需要进行跳转,Blazor支持的跳转除了HTML标记外,还有个NavigationManager类。
NavigationManager类在Microsoft.AspNetCore.Components命名空间下。
改造下Index.razor。
  1. @page "/"
  2. @inject NavigationManager navigationManager
  3. <Title Level="1">Hello,DotNet宝藏库</Title>
  4. <Text Type="success">欢迎关注我的公众号!</Text>
  5. <a target="_blank" href="https://www.cnblogs.com/Counter">使用a 标记跳转</a>
  6.     <Button Danger Type="@ButtonType.Primary" OnClick="()=>DirectToCounter()">使用NavigationManager跳转</Button>
  7. @code
  8. {
  9.     private void DirectToCounter()
  10.     {
  11.         navigationManager.NavigateTo("/Counter");
  12.     }
  13. }
复制代码
这时,不论是点击链接还是点击按钮,都可以跳转到响应页面!

路由参数

路由的过程当中经常需要进行参数传递,以方便我们跳转到的新页面后进行一些操作。
Blazor传参分为两种情况:path传参以及QueryString传参。我们分别介绍下这两种传参的方法。
path传参

path传参就是把参数组合在URL路径里,接收参数的页面需要在@page以相同的名称填充参数。并添加Parameter特性对参数进行修饰。
先改造下Counter.razor
  1. @page "/counter"
  2. @page "/counter/{initNum}"
  3. <Title Level="2">Counter</Title>
  4. <p role="status">Current count: @currentCount</p>
  5. <Button @onclick="IncrementCount" Type="primary">AntDesign 按钮</Button>
  6. @code {
  7.     [Parameter]
  8.     public string initNum{ get; set; }
  9.     private int currentCount = 0;
  10.    
  11.     protected override void OnParametersSet()
  12.     {
  13.         if (!int.TryParse(initNum, out int num))
  14.         {
  15.             currentCount = 0;
  16.         }else
  17.         {
  18.             currentCount = num;
  19.         }
  20.     }
  21.     private void IncrementCount()
  22.     {
  23.         currentCount++;
  24.     }
  25.    
  26. }
复制代码
代码中,增加了一个@page "/counter/{initNum}"。{initNum}就是参数。
注意参数是不区分大小写的,但是为了更规范,建议URL全部用小写,c#代码则使用驼峰式命名。
还有Blazor并不支持可选参数,所以如果这个例子里面的initNum是可有可无的,则需要使用@page指令来定义两条路由,一条包含initNum,另一条不包含。
OnParametersSet或OnParametersSetAsync中,我们把initNum赋值给currentCount。
修改下Index.razor中的DirectToCounter方法:
  1. private void DirectToCounter()
  2.     {
  3.         navigationManager.NavigateTo("/Counter/10");
  4.     }
复制代码
运行起来,当点击使用NavigationManager跳转按钮后,Counter.razor中的currentCount为10。

QueryString 传参

除了把参数直接拼接在URL路径(path)里,另一种常用的传递参数的方法是,将参数做为QueryString传递给跳转页面,比如“/Counter?initNum=3”。我们可从 NavigationManager.Uri 属性中获取请求的查询字符串。
将Index.razor里的
使用a 标记跳转改为使用a 标记跳转
修改Counter.razor,先引入NavigationManager。
  1. @page "/counter"
  2. @inject NavigationManager navigationManager
复制代码
在OnParametersSet内获取参数
  1.         protected override void OnParametersSet()
  2.     {
  3.         //if (!int.TryParse(initNum, out int num))
  4.         //{
  5.         //    currentCount = 0;
  6.         //}else
  7.         //{
  8.         //    currentCount = num;
  9.         //}
  10.         var query = new Uri(navigationManager.Uri).Query;
  11.         Console.WriteLine(query);
  12.     }
复制代码
断点后,可以看到,从Index.razor点击链接跳转到Counter.razor后,获取到了参数:

这里有个问题,获取到的参数不是键值对,而是一串字符串。与我们的期望不同。不过还好,我们可以通过QueryHelpers.ParseQuery来获取到键值对信息。
1、添加依赖:
  1. PM> NuGet\Install-Package Microsoft.AspNetCore.WebUtilities -Version 2.2.0
复制代码
2、解析参数
  1. var queryDic = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);
复制代码

可以获取到参数值了。把代码补充完整:
  1. protected override void OnParametersSet()
  2.     {
  3.         //if (!int.TryParse(initNum, out int num))
  4.         //{
  5.         //    currentCount = 0;
  6.         //}else
  7.         //{
  8.         //    currentCount = num;
  9.         //}
  10.         var query = new Uri(navigationManager.Uri).Query;
  11.         var queryDic = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);
  12.         if (queryDic.ContainsKey("initNum"))
  13.         {
  14.             var count_str = queryDic["initNum"].ToString() ?? "";
  15.             if (!int.TryParse(count_str, out int num))
  16.             {
  17.                 currentCount = 0;
  18.             }
  19.             else
  20.             {
  21.                 currentCount = num;
  22.             }
  23.         }
  24.         else
  25.         {
  26.             currentCount = 0;
  27.         }
  28.         
  29.     }
复制代码
运行一下看看效果

路由约束

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

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

暂无,下次再会!
欢迎大家关注我的微信公众号,一起进步,一起成长

来源:https://www.cnblogs.com/gmval/archive/2023/01/05/17027356.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具