• 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

    关注我的公众号一起玩转技术

  • 相关阅读:
    面试题63 二叉搜索树的第k个结点
    面试题62 序列化二叉树
    面试题61 把二叉树打印成多行
    面试题60 按之字形顺序打印二叉树
    centos下Nginx代理访问web服务
    回文数
    两数之和--哈希表unordered_map
    删除链表的倒数第N个节点---链表的应用
    基础篇,排序(冒泡排序,快速排序)
    linuxC网络聊天室简单代码,CSDN博客迁移
  • 原文地址:https://www.cnblogs.com/kklldog/p/blazor-wasm-router.html
Copyright © 2020-2023  润新知