.Net Core开发学习(四) ——Blazor(MVVM)应用
.Net Core开发学习(四) ——Blazor(MVVM)应用MVVM(Model-View-ViewModel)MVVM,双向数据绑定。既 模型数据 与 页面显示的数据 双向绑定,改变视图数据 也会 改变模型数据。使用Blazor框架可以减少很多Js脚本代码甚至可以无Js脚本实现快速开发。当然,想要做到这点,必须浏览器与服务器保持实时连接,所以Blazor的底层是基于WebSocket的。现
.Net Core开发学习(四) ——Blazor(MVVM)应用
MVVM(Model-View-ViewModel)
MVVM,双向数据绑定。既 模型数据 与 页面显示的数据 双向绑定,改变视图数据 也会 改变模型数据。
使用Blazor框架可以减少很多Js脚本代码甚至可以无Js脚本实现快速开发。当然,想要做到这点,必须浏览器与服务器保持实时连接,所以Blazor的底层是基于WebSocket的。
现在比较出名的mvvm架构的框架有vue.js,angular.js等。
创建Blazor应用
创建完成后运行一下
OK,项目启动成功
项目结构
项目结构和web应用大体很像,可以参考.Net Core开发学习(二) ——Web应用,现在我来讲讲不同之处。
Razor组件:在Blazor应用中有很多以 .razor 结尾,这其实是 Razor组件。Razor组件是一种可重用的视图组件,类似于用户控件,可以很方便的嵌入到其他视图,在MVC应用中也可以使用。
_Host.cshtml:全局布局文件,在Startup.cs中可以看到endpoints.MapFallbackToPage("/_Host")。
在app标签中component指定如何绘制组件。
呈现模式 | 描述 |
---|---|
ServerPrerendered | 在静态 HTML 中呈现 App 组件,并包含 Blazor Server 应用的标记。 用户代理启动时,此标记用于启动 Blazor 应用。 |
Server | 呈现 Blazor 服务器应用的标记。 不包括 App 组件的输出。 用户代理启动时,此标记用于启动 Blazor 应用。 |
Static | 在静态 HTML 中呈现 App 组件。 |
App.razor:全局应用配置文件,包括路由、Layout、用户验证等配置和返回样式,详情可见Microsoft.AspNetCore.Components命名空间。
_Imports.razor:全局引用命名空间配置文件。
Razor组件
打开文件:Pages > Index.razor
@page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
<!--使用 SurveyPrompt组件-->
<SurveyPrompt Title="How is Blazor working for you?" />
@page :声明一个可处理请求的文件,"/" 指定路由
我们看到使用了 <SurveyPrompt /> 这个Razor组件。
打开文件:Pages > SurveyPrompt.razor,代码如下
<div class="alert alert-secondary mt-4" role="alert">
<span class="oi oi-pencil mr-2" aria-hidden="true"></span>
<strong>@Title</strong>
<span class="text-nowrap">
Please take our
<a target="_blank" class="font-weight-bold" href="https://go.microsoft.com/fwlink/?linkid=2112271">brief survey</a>
</span>
and tell us what you think.
</div>
@code {
// Demonstrates how a parent component can supply parameters
[Parameter]
public string Title { get; set; }
}
在 @code 中,声明了一个参数 Title,使用 [Parameter] 属性修饰。
运行效果
可以看到,SurveyPrompt.razor 已经出现在了 Index.razor 中。
数据绑定
(1) 单项绑定
打开文件:Pages > Counter.razor,代码如下
@page "/counter"
<h1>Counter</h1>
<!--显示变量-->
<p>Current count: @currentCount</p>
<!--绑定事件-->
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
//定义变量
private int currentCount = 0;
//修改变量
private void IncrementCount()
{
currentCount++;
}
}
可以看到,代码 <p> 标签中显示 currentCount,当 点击button 时执行 IncrementCount() 方法。
运行效果
(2) 双项绑定
创建文件:Pages > FormTest.razor
@page "/FormTest"
<h1>FormTest</h1>
姓名:
<input type="text" @bind="@Name" />
@switch (nameError)
{
case 1:
<div>警告:姓名不能小于3位大于5位</div>
break;
}
<br />
生日:
<input type="datetime" @bind="@Birthday" />
@switch (birthdayError)
{
case 1:
<div>警告:请输入一个正确的生日</div>
break;
}
<br />
<br />
<br />
输出
<br />
姓名:@Name
<br />
生日:@Birthday
@code {
private string name = "";
private string Name
{
get { return name; }
set
{
if (value.Length < 3 || value.Length > 5)
{
nameError = 1;
}
else
{
nameError = -1;
name = value;
}
}
}
private int nameError = -1;
private DateTime birthday = new DateTime(2001, 1, 1);
private DateTime Birthday
{
get { return birthday; }
set
{
if (value < new DateTime(1900, 1, 1) || value > DateTime.Now)
{
birthdayError = 1;
}
else
{
birthdayError = -1;
birthday = value;
}
}
}
private int birthdayError = -1;
}
运行效果
是不是感觉跟wpf、winform等桌面应用差不多了,哈哈,在以前的web应用中想实现这些功能肯定是要写JS的,现在直接绑定就可以了。
数据加载
查看方法:Startup.cs > ConfigureServices(),代码如下
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
//添加一个单例WeatherForecastService依赖注入
services.AddSingleton<WeatherForecastService>();
}
添加了一个 单例WeatherForecastService依赖注入 ,为页面提供数据服务。
打开文件:Pages > FetchData.razor,代码如下
@page "/fetchdata"
@using BlazorApp1.Data
@inject WeatherForecastService ForecastService
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from a service.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
}
}
@inject:将依赖注入进页面。
OnInitializedAsync():异步初始化,同步使用 OnInitialized()
在OnInitializedAsync方法中将数据加载入forecasts,再绑定数据到页面上。
Blazor生命周期
初始化事件: 在组件从其父组件接收初始参数后初始化将调用 OnInitializedAsync 和 OnInitialized。
OnInitialized():组件初始化方法(同步),写法如下。
protected override void OnInitialized()
{
...
}
OnInitializedAsync():组件初始化方法(异步),写法如下。
protected override async Task OnInitializedAsync()
{
await ...
}
参数设置事件: 在组件已接收到的参数从其父和值被分配给属性被调用,并且初始化后每次呈现组件都将执行,OnParametersSetAsync 和 OnParametersSet。
OnParametersSet():参数设置方法(同步),写法如下。
protected override void OnParametersSet()
{
...
}
OnParametersSetAsync():参数设置方法(异步),写法如下。
protected override async Task OnParametersSetAsync()
{
await ...
}
渲染完成事件: 在组件完成渲染后调用,OnAfterRenderAsync 和 OnAfterRender。
OnAfterRender():渲染完成方法(同步),写法如下。
protected override void OnAfterRender(bool firstRender)
{
...
}
OnAfterRenderAsync():渲染完成方法(异步),写法如下。
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await ...
}
布局
默认布局
打开文件:App.razor
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
在 Router > Found > RouteView[DefaultLayout] 处设置布局
使用指定布局
创建文件: Share > TestLayout.razor
@inherits LayoutComponentBase
<h3 style="margin: 15px;">TestLayout</h3>
<div class="main" style="margin:15px;">
@Body
</div>
@code {
}
修改文件: Pages > Error.razor
在文件顶部添加一行代码
@layout TestLayout
运行项目,地址栏输入 /error,效果如下
因为页面与Layout都是组件,所以布局也可以嵌套,大家可自行尝试。
数据验证
创建文件: Data > User.cs
public class User
{
[Required]
public string Name { get; set; }
}
创建文件: Page > Users > CreateUser.razor
@page "/User/Create"
<h3>CreateUser</h3>
<EditForm Model="@user" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText id="name" @bind-Value="user.Name" />
<button type="submit">Submit</button>
</EditForm>
@code {
private Data.User user = new Data.User();
private void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
运行效果
OK,一个简单的Blazor应用就完成啦。
更多推荐
所有评论(0)