.Net Core开发学习(四) ——Blazor(MVVM)应用

.Net Core开发学习(四) ——Blazor(MVVM)应用


MVVM(Model-View-ViewModel)

MVVM,双向数据绑定。既 模型数据页面显示的数据 双向绑定,改变视图数据 也会 改变模型数据
使用Blazor框架可以减少很多Js脚本代码甚至可以无Js脚本实现快速开发。当然,想要做到这点,必须浏览器与服务器保持实时连接,所以Blazor的底层是基于WebSocket的。

现在比较出名的mvvm架构的框架有vue.js,angular.js等。


创建Blazor应用

.Net Core开发学习(四) ——Blazor(MVVM)应用_第1张图片
.Net Core开发学习(四) ——Blazor(MVVM)应用_第2张图片

创建完成后运行一下

.Net Core开发学习(四) ——Blazor(MVVM)应用_第3张图片
OK,项目启动成功


项目结构

.Net Core开发学习(四) ——Blazor(MVVM)应用_第4张图片
项目结构和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 Title="How is Blazor working for you?" />

@page :声明一个可处理请求的文件,"/" 指定路由

我们看到使用了 这个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>@Titlestrong>

    <span class="text-nowrap">
        Please take our
        <a target="_blank" class="font-weight-bold" href="https://go.microsoft.com/fwlink/?linkid=2112271">brief surveya>
    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] 属性修饰。


运行效果

.Net Core开发学习(四) ——Blazor(MVVM)应用_第5张图片

可以看到,SurveyPrompt.razor 已经出现在了 Index.razor 中。


数据绑定

(1) 单项绑定

打开文件:Pages > Counter.razor,代码如下

@page "/counter"

<h1>Counterh1>


<p>Current count: @currentCountp>


<button class="btn btn-primary" @onclick="IncrementCount">Click mebutton>

@code {
	//定义变量
    private int currentCount = 0;
	
	//修改变量
    private void IncrementCount()
    {
        currentCount++;
    }
}

可以看到,代码

标签中显示 currentCount,当 点击button 时执行 IncrementCount() 方法。


运行效果
.Net Core开发学习(四) ——Blazor(MVVM)应用_第6张图片

(2) 双项绑定

创建文件:Pages > FormTest.razor

@page "/FormTest"

<h1>FormTesth1>

姓名:
<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;
}

运行效果

.Net Core开发学习(四) ——Blazor(MVVM)应用_第7张图片

是不是感觉跟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 forecasth1>

<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>Dateth>
                <th>Temp. (C)th>
                <th>Temp. (F)th>
                <th>Summaryth>
            tr>
        thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()td>
                    <td>@forecast.TemperatureCtd>
                    <td>@forecast.TemperatureFtd>
                    <td>@forecast.Summarytd>
                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;">TestLayouth3>

<div class="main" style="margin:15px;">
    @Body
div>

@code {

}

修改文件: Pages > Error.razor

在文件顶部添加一行代码

@layout TestLayout

运行项目,地址栏输入 /error,效果如下
.Net Core开发学习(四) ——Blazor(MVVM)应用_第8张图片
因为页面与Layout都是组件,所以布局也可以嵌套,大家可自行尝试。


数据验证

创建文件: Data > User.cs

public class User
{
    [Required]
    public string Name { get; set; }
}

创建文件: Page > Users > CreateUser.razor

@page "/User/Create"
<h3>CreateUserh3>

<EditForm Model="@user" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <InputText id="name" @bind-Value="user.Name" />

    <button type="submit">Submitbutton>
EditForm>

@code {
    private Data.User user = new Data.User();

    private void HandleValidSubmit()
    {
        Console.WriteLine("OnValidSubmit");
    }
}

运行效果
.Net Core开发学习(四) ——Blazor(MVVM)应用_第9张图片

OK,一个简单的Blazor应用就完成啦。

你可能感兴趣的:(#,.NET,Core)