专栏首页.NET开发那点事ASP.NET Core Blazor Webassembly 之 路由

ASP.NET Core Blazor Webassembly 之 路由

web最精妙的设计就是通过url把多个页面串联起来,并且可以互相跳转。我们开发系统的时候总是需要使用路由来实现页面间的跳转。传统的web开发主要是使用a标签或者是服务端redirect来跳转。那今天来看看Blazor是如何进行路由的。

使用@page指定组件的路由path

我们可以在Blazor里给每个组件指定一个path,当路由匹配的时候会显示这个组件。

@page "/page/a"

 <h2>
     PAGE A
 </h2>

@code {
 
}

访问/page/a 看到Page A页面被渲染出来了。

注意:如果是在浏览器里敲入url按回车切换页面,会发生一次http请求,然后重新渲染blazor应用。

使用a标签进行页面跳转

a标签作为超链接是我们web开发最常用的跳转方式,blazor同样支持。 新建Page B

@page "/page/b"

 <h2>
     PAGE B
 </h2>

@code {
 
}

在Page A页面添加一个a标签进行跳转:

@page "/page/a"

 <h2>
     PAGE A
 </h2>
<p>
    <a href="/page/b">Page B</a>
</p>

@code {
 
}

运行一下试试:

注意:使用a连接在页面间进行跳转不会发生http请求到后台,页面是直接在前端渲染出来的。

通过路由传参

通过http的url进行页面间传参是我们web开发的常规操作。下面我们演示下如何从Page A传递一个参数到Page B。我们预设Page A里面有个UserName需要传递到Page B,并且显示出来。

通过path传参

通过url传参一般有两种方式,一种是直接把参数组合在path里,比如“/page/b/小明”这样。

修改Page A:

@page "/page/a"

 <h2>
     PAGE A
 </h2>
<p>
    <a href="/page/b/@userName">Page B</a>
</p>

@code {
    private string userName = "小明";
}

通过把userName组合到path上传递给Page B。

修改Page B:

@page "/page/b/{userName}"

 <h2>
     PAGE B
 </h2>
<p>
    userName: @userName
</p>

@code {
    [Parameter]
    public string userName { get; set; }
}

Page B 使用一个“/page/b/{userName}” pattern来匹配userName,并且userName需要标记[Parameter]并且设置为public。

通过QueryString传参

除了把参数直接拼接在path里,我们还习惯通过QueryString方式传递,比如“/page/b?username=小明”。

修改Page A:

@page "/page/a"

<h2>
    PAGE A
</h2>
<p>
    <a href="/page/b?username=@userName">Page B</a>
</p>

@code {
    private string userName = "小明";
}

首先安装一个工具库:

Install-Package Microsoft.AspNetCore.WebUtilities -Version 2.2.0

修改Page B:

@page "/page/b"

<h2>
    PAGE B
</h2>
<p>
    userName: @UserName
</p>

@using Microsoft.AspNetCore.WebUtilities;

@inject NavigationManager NavigationManager;

@code {
    [Parameter]
    public string UserName { get; set; }


    protected override void OnInitialized()
    {
        var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
        QueryHelpers.ParseQuery(uri.Query).TryGetValue("username", out Microsoft.Extensions.Primitives.StringValues userName);
        Console.WriteLine(NavigationManager.Uri);
        UserName = userName.ToString();
        Console.WriteLine(UserName);

        base.OnInitialized();
    }
}

页面获取QueryString的传参比较麻烦,Blazor并没有进行封装。所以我们需要通过QueryHelpers.ParseQuery方法手工把QueryString格式化成字典形式,然后获取对应的参数。QueryHelpers类存在Microsoft.AspNetCore.WebUtilities这个库里,需要通过nuget安装。

NavLink是个导航组件,它其实就是封装了a标签。当选中的时候,也就是当前的url跟它的href一致的时候,会自动在class上加上active类,所以可以用来控制选中的样式。默认的3个导航菜单就是用的NavLink。

比如导航到counter的NavLink:

   <NavLink class="nav-link" href="counter">
                <span class="oi oi-plus" aria-hidden="true"></span> Counter
    </NavLink>

最后翻译成html:

<a href="counter" class="nav-link active">
                <span class="oi oi-plus" aria-hidden="true"></span> Counter
</a>

有的时候我们可能需要在代码里进行导航,如果是JavaScript我们会用window.location来切换页面,Blazor为我们提供了相应的封装:NavigationManager。使用NavigationManager可以通过代码直接进行页面间的跳转。我们在Page A页面放个按钮然后通过按钮的点击事件进行跳转:

@page "/page/a"

<h2>
    PAGE A
</h2>
<p>
   <button @onclick="GoToB">
       go to B
   </button>
</p>

@inject NavigationManager NavigationManager
@code {

    private void GoToB()
    {
        NavigationManager.NavigateTo("/page/b?username=小猫");
    }

}

修改Page A的代码,注入NavigationManager对象,通过NavigationManager.NavigateTo方法进行跳转。

扩展Back方法

Blazor封装的NavigationManager咋一看以为跟WPF的NavigationService一样,我想当然的觉得里面肯定有个Back方法可以进行后退。但是查了一番发现还真的没有,这就比较尴尬了,没办法只能使用JavaScript来实现了。

为了方便我们给NavigationManager直接写个扩展方法吧。 首先修改Program把IServiceCollection暴露出来:

    public class Program
    {
        public static IServiceCollection Services;

        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("app");

            builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
            Services = builder.Services;

            await builder.Build().RunAsync();
        }
    }

扩展类:

  public static class Ext
    {
        public static void Back(this NavigationManager navigation)
        {
            var jsruntime = Program.Services.BuildServiceProvider().GetService<IJSRuntime>();
            jsruntime.InvokeVoidAsync("history.back");
        }
    }

这个扩展方法很简单,从DI容器里获取IJSRuntime的实例对象,通过它去调用JavaScript的history.back方法。

修改Page B:

@page "/page/b"

<h2>
    PAGE B
</h2>
<p>
    userName: @UserName
</p>
<p>
    <button @onclick="GoBack">
        Go back
    </button>
</p>

@using Microsoft.AspNetCore.WebUtilities;

@inject NavigationManager NavigationManager;

@code {
    [Parameter]
    public string UserName { get; set; }


    protected override void OnInitialized()
    {
        var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
        QueryHelpers.ParseQuery(uri.Query).TryGetValue("username", out Microsoft.Extensions.Primitives.StringValues userName);
        Console.WriteLine(NavigationManager.Uri);
        UserName = userName.ToString();
        Console.WriteLine(UserName);

        base.OnInitialized();
    }

    private void GoBack()
    {
        NavigationManager.Back();
    }
}

在Page B页面上添加一个按钮,点击调用NavigationManager.Back方法就能回到上一页。

总结

到此Blazor路由的内容学习的差不多了,整体上没有什么特别的,就是NavigationManager只有前进方法没有后退是比较让我震惊的。

相关内容:

ASP.NET Core Blazor Webassembly 之 数据绑定 ASP.NET Core Blazor Webassembly 之 组件 ASP.NET Core Blazor 初探之 Blazor WebAssembly ASP.NET Core Blazor 初探之 Blazor Server

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ASP.NET Core Blazor Webassembly 之 数据绑定

    上一次我们学习了Blazor组件相关的知识(Asp.net Core Blazor Webassembly - 组件)。这次继续学习Blazor的数据绑定相关的...

    kklldog
  • angularjs input上传图片前获取图片的Size

    首先我们需要一个指令来追踪input的change。ngChage不适用input[file]。 app.directive("fileread", [func...

    kklldog
  • If WCF Service side and Client side config is different?!

    from stackoverflow  http://stackoverflow.com/questions/4879310/when-setting-up-a...

    kklldog
  • 强悍!机器人就是这样给葡萄做缝合手术的

    ---- 据英国《每日邮报》报道,最近,一段机器人缝合葡萄皮的视频在网络走红。视频中,一个名为“达芬奇系统”的机器人先是撕开了一个葡萄的皮,然后又将葡萄皮 完...

    机器人网
  • C++核心准则​GSL.view:视图

    These types allow the user to distinguish between owning and non-owning pointers...

    面向对象思考
  • 医用机器人,第四代达芬奇操刀上岗

    2015年5月,一段机器人缝合葡萄皮的视频在网络走红。视频中,一个名为“达芬奇系统”的机器人先是撕开了一个葡萄的皮,然后又将葡萄皮完好地缝合。“达芬奇系统”是当...

    AiTechYun
  • 把命托付给手术机器人,比人更靠谱?

    ---- ? 适合在狭小空间操控的机器人手术,几乎已经涵盖了外科所有科室,高年资医生累积的手术经验会因此贬值吗? 2013年前11个月,美国FDA共接到36...

    机器人网
  • 英国首例机器人心脏手术致死案揭晓,机器“暴走”竟是人为!

    2015年2月,英国首例机器人心瓣修复手术进行。原本是一场最尖端医疗AI技术的展示,没想到却成了一场鲜血四溅的惨案。

    新智元
  • Qt开源作品4-网络调试助手

    网络调试助手和串口调试助手是一对的,用Qt开发项目与硬件通信绝大部分都是要么串口通信(RS232 RS485 Modbus等),要么就是网络通信(TCP UDP...

    feiyangqingyun
  • JAVAWEB复习-JS

    特点:信息动态交互,不可直接访问本地磁盘,只要是可以解析js的浏览器都可以跨平台执行

    阮键

扫码关注云+社区

领取腾讯云代金券