Blazor带我重玩前端(五)
概述
本文主要讨论Blazor事件内容,由于blazor事件部分很多,所以会分成上下两篇,本文为第一篇,后续会有第二篇。
我们可以视组件是一个类,我们先看一下前文所说的Index.Razor页面生成的C#代码。
在此,先补充一下该页面的原始代码:
1: @page "/"
2: @layout MyLayout
3: <h1>Hello, world!</h1>
4:
5: Welcome to your new app.
6:
7: <SurveyPrompt Title="How is Blazor working for you?" />
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Index.razor页面在项目编译后会生成Index.razor.g.cs文件,其位置如图所示,在obj文件夹下面:

具体的源码如下:
1: [Microsoft.AspNetCore.Components.LayoutAttribute(typeof(MyLayout))]
2: [Microsoft.AspNetCore.Components.RouteAttribute("/")]
3: public partial class Index : Microsoft.AspNetCore.Components.ComponentBase
4: {
5: #pragma warning disable 1998
6: protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
7: {
8: __builder.AddMarkupContent(0, "<h1>Hello, world!</h1>\r\n\r\nWelcome to your new app.\r\n\r\n");
9: __builder.OpenComponent<BlazorApp.Client.Shared.SurveyPrompt>(1);
10: __builder.AddAttribute(2, "Title", "How is Blazor working for you?");
11: __builder.CloseComponent();
12: }
13: #pragma warning restore 1998
14: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
可以看到,以上代码并不难理解,同时它还有两个特性,一个是布局的标识,一个是路由的标识。紧接着就是该类重写了BuildRenderTree方法,这个以后会说。需要提醒的是,大家在写Blazor项目遇到问题时,可以多查看razor页面所生成的C#代码。
创建简单组件
需要注意的是,在Blazor项目中,包括razor页面,布局以及组件都隐式或显示的继承自ComponentBase的。
在Blazor.Client项目的Shared文件夹中,我们创建一个Components文件夹用于存放我们自定义的组件。
(1)创建页面,并暂且先使用下面的默认内容

(2)然后在_Imports.razor文件中添加@using BlazorApp.Client.Shared.Components,以使得该组件可以全局使用,从这个引用的命名空间来看,我们新建的组件的命名空间默认就是文件所在的位置

(3)在Index.razor页面使用
(4)运行后的结果如图所示

单项绑定
如果读者接触了比较多的前端框架,可能会对理解单项绑定有很大的帮助,这实际上一种插值或者说是动态数据的占位(变量)。
大部分情况下,我们都希望我们的组件是可以输出动态内容,那么我们应该如何实现呢?这个时候我们就需要在页面上写一写C#代码了。
(1)在MyComponent组件中添加参数,并标记[Parameter]特性
(2)在Index页面上,添加按钮和事件功能,可以参考Counter页面的按钮
这个页面的功能我们暂时只关注如何传值即可,也就是在调用MyComponent组件的时候,调用其属性Counter并赋值。
(3)运行效果如下所示

组件事件
添加组件自定义事件,其实就是声明一个EventCallback<int>类型的组件参数,如下代码所示:
1: [Parameter]
2: public EventCallback<int> EventSample { get; set; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
(1)自定义组件修改
增加一个计数方法,可以参考Counter中代码。在IncrementCount方法中,采用await ClickCountCallback.InvokeAsync(currentCount*2)方式传值给Index.Razor页面,页面源码:
1: @*<h3>My Component</h3>*@
2:
3: 这里是自定义组件的区域,我点击了几次 <strong style="color: red">@currentCount</strong>
4: <br>
5: <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
6:
7: @code {
8: private int currentCount { get; set; }
9:
10: [Parameter]
11: public EventCallback<int> ClickCountCallback { get; set; }
12:
13: private async Task IncrementCount()
14: {
15: currentCount++;
16: await ClickCountCallback.InvokeAsync(currentCount*2);
17: }
18: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
(2)Index.razor页面
1: @page "/"
2: @layout MyLayout
3: <h1> </h1>
4:
5: @*Welcome to your new app.*@
6:
7: @*<SurveyPrompt Title="How is Blazor working for you?" />*@
8:
9: <h2>Index页面的CurrentCount=<strong style="color: red">@currentCount</strong></h2>
10:
11: <br>
12: <MyComponent ClickCountCallback="IncrementCount1" />
13: <br />
14:
15: @code {
16: private int currentCount;
17:
18: private void IncrementCount1(int value)
19: {
20: currentCount = value;
21: }
22: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
使用currentCount接收自定义组件中传来的值。
运行效果如下:
Index.razor页面生成的C#源码如下所示:

会往RenderTreeBuilder对象中添加AddAttribute,用于接收自定义组件回调过来的值。
Blazor带我重玩前端(五)的更多相关文章
- Blazor带我重玩前端(一)
写在前面 曾经我和前端朋友聊天的时候,我说我希望有一天可以用C#写前端,不过当时更多的是美好的想象,而现在这一切正变得真实…… 什么是Blazor 我们知道浏览器可以正确解释并执行JavaScript ...
- Blazor带我重玩前端(三)
写在前面 需要升级VS2019以及.NET Core到最新版(具体的最低支持,我已经忘了,总是越新支持的就越好),以更好的支持自己开发Blazor项目. WebAssembly 搜索Blazor模板 ...
- Blazor带我重玩前端(四)
布局 Blazor中的布局和MVC中的布局是类似的. 创建布局 新建一个Razor页面,所有新增的布局都要继承LayoutComponentBase,同时标识自定义内容的输出位置,即标识Body的位置 ...
- Blazor带我重玩前端(二)
概览 Blazor目前有两种托管模式,一种是Server-Side模式,一种是WebAssembly模式.官方首先支持的是Service-Side模式,使用WebAssembly模式,需要更新到最新版 ...
- Blazor带我重玩前端(六)
本文主要讨论Blazor事件内容,由于blazor事件部分很多,所以会分成上下两篇,本文为第二篇. 双向绑定 概述 如图所示 当点击单项绑定的时候,MyOnewayComponent里的属性值会发生变 ...
- 重学前端 --- Promise里的代码为什么比setTimeout先执行?
首先通过一段代码进入讨论的主题 var r = new Promise(function(resolve, reject){ console.log("a"); resolve() ...
- 重学前端--js是面向对象还是基于对象?
重学前端-面向对象 跟着winter老师一起,重新认识前端的知识框架 js面向对象或基于对象编程 以前感觉这两个在本质上没有什么区别,面向对象和基于对象都是对一个抽象的对象拥有一系列的行为和状态,本质 ...
- node十年心酸史,带你了解大前端的由来!
前言 近年来,随着前端的丰富,前后端分离是趋势.各种东西如雨后春笋一般,层出不穷.node.js的出现,使前端真正意义上变成了大前端. 前端由来之HTML发展史 1990 年,Tim Berners- ...
- 前端(五)-Vue简单基础
1. Vue概述 Vue (读音/vju/, 类似于view)是一套用于构建用户界面的渐进式框架,发布于2014年2月. 与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用. Vue的核心库只 ...
随机推荐
- Latex—参考文献
在写文章的最后最让我头疼的就是参考文献的问题了.网上的资料也有很多,这里整合了很多资料得出了一个用bib文件的方法. 1. 显示确定参考文献(一句没什么用的废话). 2. 利用谷歌学术(镜像),如 ...
- MR程序的几种提交运行模式
本地模式运行 1-在windows的eclipse里面直接运行main方法 将会将job提交给本地执行器localjobrunner 输入输出数据可以放在本地路径下 输入输出数据放在HDFS中:(hd ...
- 关于python中的 take no arguments 的解决方法
针对第四章编写的代码出现的错误做一个总结 Traceback (most recent call last): File "H:\image\chapter4\p81_chongxie.py ...
- 记录一次jmeter脚本开发缺少utf-8惹的祸
背景:需要模拟余额发放,并进行大批量的发放,我就想到了jmeter.就是几个简单的接口,我想很简单,就上手,没想到最后鸡鸡,害我查了半天原因. 操作:我编写的脚本: 请求默认值的内容编码我也是为空,当 ...
- 【NOIP2015四校联训Day7】 题 题解(Tarjan缩点+DFS)
前言:没错,这题的名字就这么直白.我们考试题. ------------------ 你需要完成$n$道题目.有一些题目是相关的,当你做一道题的时候,如果你做过之前对它有帮助的题目,你会更容易地做出它 ...
- 修改当前项目maven仓库地址
pom.xml中修改 <repositories> <repository> <id>nexus-aliyun</id> <name>Nex ...
- Nginx.conf参数配置详解
Nginx的配置文件nginx.conf配置详解如下: user nginx nginx; #Nginx用户及组:用户 组.window下不指定 worker_processes 8; #工作进程:数 ...
- IDEA操作jdbc总结
今天学习IDEA操作JDBC,MySQL包导入到项目 // 1.注册数据库的驱动// Driver driver=new com.mysql.jdbc.Driver();// DriverManage ...
- ALGEBRA-1 向量空间
向量空间对加法封闭 对数乘封闭 直和:表示的唯一性
- 树堆(Treap)学习笔记 2020.8.12
如果一棵二叉排序树的节点插入的顺序是随机的,那么这样建立的二叉排序树在大多数情况下是平衡的,可以证明,其高度期望值为 \(O( \log_2 n )\).即使存在一些极端情况,但是这种情况发生的概率很 ...