zoukankan      html  css  js  c++  java
  • Blazor 修仙之旅

    一.前言

    在第一篇文章中,有提到过组件(Component)这个概念。组件在 Blazor 中是必不可少的,UI 全靠它组装起来,和前端的 JS 组件是一个意思,比如:vue component、react component 等等。借用官方文档的描述:

    Blazor 应用是使用组件构建的。 组件是自包含的用户界面 (UI) 块,例如页、对话框或窗体。 组件包含插入数据或响应 UI 事件所需的 HTML Tag和处理逻辑。 组件非常灵活且轻量。 可在项目之间嵌套、重复使用和共享。

    二.组件

    组件一般以 .razor 为文件名后缀,且组件名必须以大写字母开头(猜测可能是和VUE里的命名限制一样,表面和Html标签名重复)。

    我们新建的项目,Shared 文件夹中就有三个组件:

    image-20200529233527594

    左侧导航菜单组件:

    image-20200529233556081

    在主布局组件中应用了导航菜单组件:

    image-20200529233635146

    更多关于组件的资料请查阅官方文档:创建和使用 ASP.NET Core Razor 组件

    三.数据绑定

    1.介绍

    Razor 组件通过名为 @bind 的HTML元素属性提供数据绑定功能,这个绑定是双向的。

    @bind 是区分大小写的,例如:@BIND@Bind 都是错误的,下面写了一个例子,将 CurrentValue 绑定到两个文本框中。

    <div class="row">
        <div class="col-6">
            <input class="form-control" type="text" @bind="CurrentValue" />
        </div>
        <div class="col-6">
            <input class="form-control" type="text" @bind="CurrentValue" />
        </div>
    </div>
    
    <div class="row">
        <button class="btn btn-primary" @onclick="ChangeValue">变 更</button>
    </div>
    
    @code
    {
        public int CurrentValue { get; set; } = 0;
    
        private void ChangeValue()
        {
            CurrentValue ++;
        }
    }
    

    需要注意的是在文本框的绑定中,仅当呈现组件时,UI才会更新文本框,而不响应于更改属性的值。由于组件是在事件处理程序代码执行后呈现的,因此属性更新通常在触发事件处理程序后立即反映在UI中。

    @bind="CurrentValue" 等同于以下代码:

    <input value="@CurrentValue"
        @onchange="@((ChangeEventArgs __e) => CurrentValue = 
            __e.Value.ToString())" />
            
    @code {
        public int CurrentValue { get; set; } = 0;
    }
    

    点击按钮,变更了值,也会应用到文本框中:

    2.变更绑定事件

    上面小节中,默认绑定了 onchange 事件,只有文本框失去焦点才会触发,体验不是很好,那么可不可以在输入的时候就同步更新值呢,当然是可以的,解决方案就是变更绑定事件为 oninput,通过设置@bind:event属性来变更绑定事件:

    <div class="col-6">
        <input class="form-control" type="text" @bind="CurrentValue" @bind:event="oninput" />
    </div>
    <div class="col-6">
        <input class="form-control" type="text" @bind="CurrentValue" @bind:event="oninput" />
    </div>
    

    3.输入错误的值

    我们设置的 CurrentValue 的类型是 int ,如果我们输入字母,那么字母将不会被接受,同时值会恢复到输入前的正确值。

    4.子父组件数据传递

    在 vue、react 等 js 中,都有子父组件传值概念,Blazor 也不例外。

    (1)父传子

    新建一个子组件命名为 ChildComponent

    <div class="row">
        <h2>子组件</h2>
    </div>
    
    <div class="row">
        <span>Year: </span> <input class="form-control" type="text" value="@Year" />
    </div>
    
    @code {
        [Parameter]
        public int Year { get; set; }
    
        [Parameter]
        public EventCallback<int> YearChanged { get; set; }
    }
    

    定义一个 Year 属性和 EventCallback<int> 类型的属性 YearChanged

    新建一个父组件命名为ParentComponent

    <div class="row">
        <h2>父组件</h2>
    </div>
    
    <div class="row">
        <span>ParentYear: </span> <input class="form-control" type="text" @bind="ParentYear" @bind:event="oninput"/>
    </div>
    
    <ChildComponent @bind-Year="ParentYear" />
    
    @code {
        [Parameter]
        public int ParentYear { get; set; } = 1978;
    }
    

    在页面中引用父组件:

    image-20200530002006405

    YearChanged 是一个约定命名,不能更改,更改将会报错:

    image-20200530002227725

    EventCallback 用于子父组件嵌套时公开事件,比如 YearChanged 就公开了子组件 Year 属性的 changed 事件。父组件里,通过 @bind-Year 来绑定 Year 的 changed 事件,然后将父组件 ParentYear 的值传递过去,达成父级组件向子级组件传递值。

    <ChildComponent @bind-Year="ParentYear" /> 等同于 <ChildComponent @bind-Year="ParentYear" @bind-Year:event="YearChanged" /> ,如果使用后者,那么事件命名将不会受约定命名限制。

    运行效果:

    (2)子传父(链式绑定)

    子传父,无法直接通过 @bind 来实现,需要单独指定事件处理程序和值,我们更改上面的子组件,定义一个 OnYearChanged 事件,并将其绑定到文本框的 oninput 事件,在事件里手动更新了 Year的值,并调用 YearChanged 来进行传递。

    <div class="row">
        <h2>子组件</h2>
    </div>
    
    <div class="row">
        <span>Year: </span> <input class="form-control" type="text" @oninput="OnYearChanged" value="@Year" />
    </div>
    
    @code {
        [Parameter]
        public int Year { get; set; }
    
        [Parameter]
        public EventCallback<int> YearChanged { get; set; }
    
        private Task OnYearChanged(ChangeEventArgs e)
        {
            Year = int.Parse(e.Value.ToString());
    
            return YearChanged.InvokeAsync(Year);
        }
    }
    

    运行:

    四.资料

  • 相关阅读:
    【转】ios输入框被键盘挡住的解决办法
    【转】操作系统Unix、Windows、Mac OS、Linux的故事
    mac 下删除非空文件夹
    解决Win7 64bit + VS2013 使用opencv时出现提“应用程序无法正常启动(0xc000007b)”错误
    图的邻接表表示
    图的邻接矩阵表示
    并查集
    05-树9 Huffman Codes及基本操作
    05-树7 堆中的路径
    堆的操作集
  • 原文地址:https://www.cnblogs.com/stulzq/p/12990443.html
Copyright © 2011-2022 走看看