ASP.NET Core Blazor简介和快速入门二(组件基础之事件处理)
【摘要】 大家好,我是码农刚子。上一章介绍了Blazor组件的数据绑定。接下来我们继续了解Blazor 组件事件处理相关的基础知识,希望对你有所帮助。1、事件处理1. 基本事件处理1.1 单击事件<!-- ClickEvents.razor --><div class="click-demo"> <h3>单击事件示例</h3> <!-- 基本点击事件 --> <button ...
大家好,我是码农刚子。上一章介绍了Blazor组件的数据绑定。接下来我们继续了解Blazor 组件事件处理相关的基础知识,希望对你有所帮助。
1、事件处理
1. 基本事件处理
1.1 单击事件
<!-- ClickEvents.razor -->
<div class="click-demo">
<h3>单击事件示例</h3>
<!-- 基本点击事件 -->
<button @onclick="HandleClick" class="btn btn-primary">
点击我
</button>
<!-- 带参数的事件处理 -->
<div class="button-group">
<button @onclick="() => HandleButtonClick(1)" class="btn btn-secondary">按钮 1</button>
<button @onclick="() => HandleButtonClick(2)" class="btn btn-secondary">按钮 2</button>
<button @onclick="() => HandleButtonClick(3)" class="btn btn-secondary">按钮 3</button>
</div>
<!-- 显示点击结果 -->
<div class="result">
<p>最后点击的按钮: @lastClickedButton</p>
<p>点击次数: @clickCount</p>
</div>
</div>
@code {
private int lastClickedButton = 0;
private int clickCount = 0;
private void HandleClick()
{
clickCount++;
Console.WriteLine("按钮被点击了!");
}
private void HandleButtonClick(int buttonNumber)
{
lastClickedButton = buttonNumber;
clickCount++;
StateHasChanged();
}
}
1.2 异步事件处理
<!-- AsyncEvents.razor -->
<div class="async-demo">
<h3>异步事件处理</h3>
<button @onclick="HandleAsyncClick" class="btn btn-primary" disabled="@isLoading">
@if (isLoading)
{
<span>加载中...</span>
}
else
{
<span>模拟异步操作</span>
}
</button>
<div class="result">
<p>操作结果: @operationResult</p>
<p>耗时: @elapsedTime 毫秒</p>
</div>
</div>
@code {
private bool isLoading = false;
private string operationResult = string.Empty;
private long elapsedTime = 0;
private async Task HandleAsyncClick()
{
isLoading = true;
operationResult = "操作开始...";
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
// 模拟异步操作
await Task.Delay(2000);
stopwatch.Stop();
elapsedTime = stopwatch.ElapsedMilliseconds;
operationResult = $"操作完成!数据已保存。";
isLoading = false;
StateHasChanged();
}
}
2. 表单事件处理
2.1 输入事件
<!-- FormEvents.razor -->
<div class="form-events">
<h3>表单事件处理</h3>
<div class="form-group">
<label>输入文本:</label>
<input @oninput="HandleInput"
@onchange="HandleChange"
class="form-control"
placeholder="输入内容..." />
<small>实时输入: @inputValue | 变化事件: @changeValue</small>
</div>
<div class="form-group">
<label>选择选项:</label>
<select @onchange="HandleSelectChange" class="form-control">
<option value="">请选择</option>
<option value="option1">选项一</option>
<option value="option2">选项二</option>
<option value="option3">选项三</option>
</select>
<small>选择的值: @selectedValue</small>
</div>
<div class="form-group">
<label>
<input type="checkbox" @onchange="HandleCheckboxChange" />
同意条款
</label>
<small>状态: @(isChecked ? "已选中" : "未选中")</small>
</div>
<!-- 表单提交 -->
<form @onsubmit="HandleSubmit" @onvalidSubmit="HandleValidSubmit">
<div class="form-group">
<label>用户名:</label>
<input @bind="user.Username" class="form-control" required />
</div>
<div class="form-group">
<label>邮箱:</label>
<input @bind="user.Email" type="email" class="form-control" required />
</div>
<button type="submit" class="btn btn-success">提交表单</button>
</form>
<div class="form-result">
<h4>表单数据:</h4>
<pre>@System.Text.Json.JsonSerializer.Serialize(user, new System.Text.Json.JsonSerializerOptions { WriteIndented = true })</pre>
<p>提交状态: @submitStatus</p>
</div>
</div>
@code {
private string inputValue = string.Empty;
private string changeValue = string.Empty;
private string selectedValue = string.Empty;
private bool isChecked = false;
private string submitStatus = "未提交";
private User user = new User();
private void HandleInput(ChangeEventArgs e)
{
inputValue = e.Value?.ToString() ?? string.Empty;
}
private void HandleChange(ChangeEventArgs e)
{
changeValue = e.Value?.ToString() ?? string.Empty;
}
private void HandleSelectChange(ChangeEventArgs e)
{
selectedValue = e.Value?.ToString() ?? string.Empty;
}
private void HandleCheckboxChange(ChangeEventArgs e)
{
isChecked = (bool)(e.Value ?? false);
}
private void HandleSubmit()
{
submitStatus = "表单提交(可能有验证错误)";
}
private void HandleValidSubmit()
{
submitStatus = $"表单验证通过!数据已保存 - {DateTime.Now:HH:mm:ss}";
// 这里可以调用API保存数据
}
class User
{
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
}
}
3. 鼠标和键盘事件
3.1 鼠标事件
<!-- MouseEvents.razor -->
<div class="mouse-events">
<h3>鼠标事件</h3>
<div class="interactive-area"
@onmousedown="HandleMouseDown"
@onmouseup="HandleMouseUp"
@onmousemove="HandleMouseMove"
@onmouseover="HandleMouseOver"
@onmouseout="HandleMouseOut"
@onclick="HandleAreaClick"
@ondblclick="HandleDoubleClick"
style="width: 300px; height: 200px; border: 2px solid #007bff; padding: 20px; margin: 10px 0;">
鼠标交互区域
</div>
<div class="event-log">
<h4>事件日志:</h4>
<ul>
@foreach (var log in eventLogs.TakeLast(10).Reverse())
{
<li>@log</li>
}
</ul>
</div>
<div class="mouse-info">
<p>鼠标位置: (@mouseX, @mouseY)</p>
<p>按钮状态: @(isMouseDown ? "按下" : "释放")</p>
<p>悬停状态: @(isMouseOver ? "在区域内" : "在区域外")</p>
</div>
</div>
@code {
private double mouseX = 0;
private double mouseY = 0;
private bool isMouseDown = false;
private bool isMouseOver = false;
private List<string> eventLogs = new List<string>();
private void LogEvent(string eventName)
{
eventLogs.Add($"{DateTime.Now:HH:mm:ss.fff} - {eventName}");
StateHasChanged();
}
private void HandleMouseDown(MouseEventArgs e)
{
isMouseDown = true;
LogEvent($"MouseDown - 按钮: {e.Button}, 位置: ({e.ClientX}, {e.ClientY})");
}
private void HandleMouseUp(MouseEventArgs e)
{
isMouseDown = false;
LogEvent($"MouseUp - 按钮: {e.Button}, 位置: ({e.ClientX}, {e.ClientY})");
}
private void HandleMouseMove(MouseEventArgs e)
{
mouseX = e.ClientX;
mouseY = e.ClientY;
// 注意:频繁触发,生产环境需要节流
// LogEvent($"MouseMove - 位置: ({e.ClientX}, {e.ClientY})");
}
private void HandleMouseOver(MouseEventArgs e)
{
isMouseOver = true;
LogEvent("MouseOver");
}
private void HandleMouseOut(MouseEventArgs e)
{
isMouseOver = false;
LogEvent("MouseOut");
}
private void HandleAreaClick(MouseEventArgs e)
{
LogEvent($"Click - 按钮: {e.Button}");
}
private void HandleDoubleClick(MouseEventArgs e)
{
LogEvent($"DoubleClick - 按钮: {e.Button}");
}
}
3.2 键盘事件
<!-- KeyboardEvents.razor -->
<div class="keyboard-events">
<h3>键盘事件</h3>
<div class="input-area">
<input @onkeydown="HandleKeyDown"
@onkeyup="HandleKeyUp"
@onkeypress="HandleKeyPress"
class="form-control"
placeholder="在这里输入并观察键盘事件..." />
</div>
<div class="event-log">
<h4>键盘事件日志:</h4>
<ul>
@foreach (var log in keyEventLogs.TakeLast(10).Reverse())
{
<li>@log</li>
}
</ul>
</div>
<div class="key-info">
<p>最后按下的键: @lastKey</p>
<p>Ctrl 按下: @(isCtrlPressed ? "是" : "否")</p>
<p>Shift 按下: @(isShiftPressed ? "是" : "否")</p>
<p>Alt 按下: @(isAltPressed ? "是" : "否")</p>
</div>
</div>
@code {
private string lastKey = "无";
private bool isCtrlPressed = false;
private bool isShiftPressed = false;
private bool isAltPressed = false;
private List<string> keyEventLogs = new List<string>();
private void LogKeyEvent(string eventName, KeyboardEventArgs e)
{
var log = $"{DateTime.Now:HH:mm:ss.fff} - {eventName}: Key='{e.Key}', Code='{e.Code}'";
if (e.CtrlKey) log += " [Ctrl]";
if (e.ShiftKey) log += " [Shift]";
if (e.AltKey) log += " [Alt]";
keyEventLogs.Add(log);
StateHasChanged();
}
private void HandleKeyDown(KeyboardEventArgs e)
{
lastKey = e.Key;
isCtrlPressed = e.CtrlKey;
isShiftPressed = e.ShiftKey;
isAltPressed = e.AltKey;
LogKeyEvent("KeyDown", e);
// 快捷键处理示例
if (e.CtrlKey && e.Key == "s")
{
e.PreventDefault(); // 阻止浏览器默认保存行为
LogKeyEvent("快捷键: Ctrl+S", e);
}
}
private void HandleKeyUp(KeyboardEventArgs e)
{
isCtrlPressed = e.CtrlKey;
isShiftPressed = e.ShiftKey;
isAltPressed = e.AltKey;
LogKeyEvent("KeyUp", e);
}
private void HandleKeyPress(KeyboardEventArgs e)
{
LogKeyEvent("KeyPress", e);
}
}
4. 焦点和剪贴板事件
<!-- FocusClipboardEvents.razor -->
<div class="focus-clipboard">
<h3>焦点和剪贴板事件</h3>
<div class="form-group">
<label>焦点测试输入框:</label>
<input @onfocus="HandleFocus"
@onblur="HandleBlur"
class="form-control"
placeholder="点击获取焦点,点击别处失去焦点" />
</div>
<div class="form-group">
<label>复制粘贴测试:</label>
<textarea @oncopy="HandleCopy"
@oncut="HandleCut"
@onpaste="HandlePaste"
class="form-control"
rows="3"
placeholder="在这里测试复制、剪切、粘贴操作">这是一些测试文本</textarea>
</div>
<div class="event-log">
<h4>事件状态:</h4>
<p>焦点状态: <span class="@(hasFocus ? "text-success" : "text-danger")">@(hasFocus ? "有焦点" : "无焦点")</span></p>
<p>最后操作: @lastOperation</p>
<p>剪贴板内容: @clipboardContent</p>
</div>
</div>
@code {
private bool hasFocus = false;
private string lastOperation = "无";
private string clipboardContent = "无";
private void HandleFocus(FocusEventArgs e)
{
hasFocus = true;
lastOperation = "获得焦点";
StateHasChanged();
}
private void HandleBlur(FocusEventArgs e)
{
hasFocus = false;
lastOperation = "失去焦点";
StateHasChanged();
}
private void HandleCopy(ClipboardEventArgs e)
{
lastOperation = "复制操作";
clipboardContent = "复制的内容无法直接获取(安全限制)";
StateHasChanged();
}
private void HandleCut(ClipboardEventArgs e)
{
lastOperation = "剪切操作";
clipboardContent = "剪切的内容无法直接获取(安全限制)";
StateHasChanged();
}
private void HandlePaste(ClipboardEventArgs e)
{
lastOperation = "粘贴操作";
clipboardContent = "粘贴的内容无法直接获取(安全限制)";
StateHasChanged();
}
}
5. 自定义事件处理
5.1 事件参数封装
<!-- CustomEventHandling.razor -->
<div class="custom-events">
<h3>自定义事件处理</h3>
<!-- 事件冒泡和阻止默认行为 -->
<div @onclick="HandleParentClick" style="padding: 20px; border: 2px solid red;">
<p>父级区域(点击会触发)</p>
<button @onclick="HandleChildClick"
@onclick:stopPropagation
class="btn btn-primary">
子按钮(点击不会冒泡)
</button>
<button @onclick="HandleChildClickWithPrevent"
@onclick:preventDefault
class="btn btn-secondary">
阻止默认行为的按钮
</button>
</div>
<!-- 自定义事件处理逻辑 -->
<div class="custom-actions">
<h4>自定义操作:</h4>
<button @onclick="HandleCustomAction1" class="btn btn-info">操作1</button>
<button @onclick="HandleCustomAction2" class="btn btn-info">操作2</button>
<button @onclick="async () => await HandleCustomAsyncAction()" class="btn btn-info">异步操作</button>
</div>
<div class="action-log">
<h4>操作日志:</h4>
<ul>
@foreach (var log in actionLogs.TakeLast(5).Reverse())
{
<li>@log</li>
}
</ul>
</div>
</div>
@code {
private List<string> actionLogs = new List<string>();
private void LogAction(string action)
{
actionLogs.Add($"{DateTime.Now:HH:mm:ss} - {action}");
StateHasChanged();
}
private void HandleParentClick()
{
LogAction("父级区域被点击");
}
private void HandleChildClick()
{
LogAction("子按钮被点击(事件不会冒泡)");
}
private void HandleChildClickWithPrevent()
{
LogAction("阻止默认行为的按钮被点击");
}
private void HandleCustomAction1()
{
LogAction("执行自定义操作1");
// 自定义业务逻辑
}
private void HandleCustomAction2(MouseEventArgs e)
{
LogAction($"执行自定义操作2 - 点击位置: ({e.ClientX}, {e.ClientY})");
// 自定义业务逻辑
}
private async Task HandleCustomAsyncAction()
{
LogAction("开始异步操作");
await Task.Delay(1000);
LogAction("异步操作完成");
}
}
6. 事件处理最佳实践
6.1 性能优化
<!-- OptimizedEvents.razor -->
<div class="optimized-events">
<h3>事件处理性能优化</h3>
<!-- 避免内联Lambda表达式(可能引起不必要的重渲染) -->
@foreach (var item in items)
{
<div class="item" @key="item.Id">
<span>@item.Name</span>
<!-- 好的做法:使用方法引用 -->
<button @onclick="() => DeleteItem(item.Id)" class="btn btn-sm btn-danger">删除</button>
</div>
}
<!-- 大量事件考虑使用事件委托 -->
<div class="large-list">
@foreach (var item in largeList)
{
<div class="list-item" data-id="@item.Id" data-name="@item.Name" @onclick="(e) => HandleListItemClick(e, item.Id)">
@item.Name
</div>
}
</div>
<div class="action-log">
<h4>操作日志:</h4>
<ul>
@foreach (var log in actionLogs.TakeLast(5).Reverse())
{
<li>@log</li>
}
</ul>
</div>
</div>
@code {
private List<Item> items = new List<Item>
{
new Item { Id = 1, Name = "项目1" },
new Item { Id = 2, Name = "项目2" },
new Item { Id = 3, Name = "项目3" }
};
private List<Item> largeList = Enumerable.Range(1, 100)
.Select(i => new Item { Id = i, Name = $"项目{i}" })
.ToList();
private List<string> actionLogs = new List<string>();
private void DeleteItem(int id)
{
items.RemoveAll(i => i.Id == id);
LogAction($"删除了项目 {id}");
}
private void HandleListItemClick(MouseEventArgs e, int itemId)
{
// 通过参数 itemId 就知道是哪个按钮被点击了
Console.WriteLine($"Clicked item ID: {itemId}");
}
// 添加 LogAction 方法
private void LogAction(string action)
{
actionLogs.Add($"{DateTime.Now:HH:mm:ss} - {action}");
StateHasChanged();
}
class Item
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
}
7. 常用事件总结
|
事件类型 |
指令 |
事件参数 |
说明 |
|
点击事件 |
|
|
鼠标点击 |
|
双击事件 |
|
|
鼠标双击 |
|
鼠标移动 |
|
|
鼠标移动 |
|
鼠标按下 |
|
|
鼠标按下 |
|
鼠标释放 |
|
|
鼠标释放 |
|
键盘按下 |
|
|
键盘按下 |
|
键盘释放 |
|
|
键盘释放 |
|
输入事件 |
|
|
输入时触发 |
|
变化事件 |
|
|
值变化时触发 |
|
获得焦点 |
|
|
元素获得焦点 |
|
失去焦点 |
|
|
元素失去焦点 |
|
表单提交 |
|
|
表单提交 |
以上就是关于《ASP.NET Core Blazor简介和快速入门二(组件基础之数据绑定)》的全部内容,希望你有所收获。关注、点赞,持续分享。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)