溫故知新,DotNet Core 遇見 Blazor-FluentUI-,屬於未來的 SPA 框架

什麼是 Blazor

基於. Net Core 提供客戶端 Web 開發的優勢

使用. NET 進行客戶端 Web 開發可提供以下優勢:

Blazor 組件

Blazor應用基於組件。Blazor中的組件是指 UI 元素,例如頁面、對話框或數據輸入窗體。

Blazor 使用 UI 構成的自然 HTML 標記。下面的 Razor 標記演示了一個組件 (Dialog.razor),它顯示一個對話框,並處理在用戶選擇按鈕時發生的事件:

<div class="card" style="width:22rem">
    <div class="card-body">
        <h3 class="card-title">@Title</h3>
        <p class="card-text">@ChildContent</p>
        <button @onclick="OnYes">Yes!</button>
    </div>
</div>

@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public string Title { get; set; }

    private void OnYes()
    {
        Console.WriteLine("Write to the console in C#! 'Yes' button selected.");
    }
}

在上述示例中,OnYes是由按鈕的onclick事件觸發的 C# 方法。對話框的文本 (ChildContent) 和標題 (Title) 由在其 UI 中使用此組件的下述組件提供。

使用 HTML 標記將Dialog組件嵌入到另一個組件中。在以下示例中,Index 組件 (Pages/Index.razor) 使用前面的Dialog組件。標記的Title屬性向Dialog組件的Title屬性傳遞標題的值。Dialog組件的文本 (ChildContent) 由<Dialog>元素的內容設置。向Index組件添加Dialog組件後,Visual Studio中的IntelliSense可加快使用語法和參數補全進行開發的速度。

@page "/"

<h1>Hello, world!</h1>

<p>
    Welcome to your new app.
</p>

<Dialog Title="Learn More">
    Do you want to <i>learn more</i> about Blazor?
</Dialog>

在瀏覽器中訪問父級Index組件時,將呈現該對話框。當用戶選擇此按鈕時,瀏覽器的開發人員工具控制檯會顯示由OnYes方法編寫的消息:

組件呈現爲瀏覽器文檔對象模型(DOM)的內存中表現形式,它被稱爲 “呈現樹”,用於以靈活高效的方式更新 UI。

文檔對象模型 (DOM) 是 HTML 和 XML 文檔的編程接口。它提供了對文檔的結構化的表述,並定義了一種方式可以使從程序中對該結構進行訪問,從而改變文檔的結構,樣式和內容。DOM 將文檔解析爲一個由節點和對象(包含屬性和方法的對象)組成的結構集合。簡言之,它會將 web 頁面和腳本或程序語言連接起來。

一個 web 頁面是一個文檔。這個文檔可以在瀏覽器窗口或作爲 HTML 源碼顯示出來。但上述兩個情況中都是同一份文檔。文檔對象模型(DOM)提供了對同一份文檔的另一種表現,存儲和操作的方式。DOM 是 web 頁面的完全的面向對象表述,它能夠使用如 JavaScript 等腳本語言進行修改。

Blazor Web Assembly

Blazor Web Assembly單頁應用(SPA)框架,用於使用.NET生成交互式客戶端 Web 應用。Blazor Web Assembly使用無插件或將代碼重新編譯爲其他語言的開放式 Web 標準。Blazor Web Assembly適用於所有新式 Web 瀏覽器,包括移動瀏覽器。

通過WebAssembly(縮寫爲wasm),可在 Web 瀏覽器內運行.NET代碼。Web Assembly是針對快速下載和最大執行速度優化的壓縮字節碼格式。Web Assembly是開放的 Web 標準,支持用於無插件的 Web 瀏覽器。

Web Assembly代碼可通過JavaScript(稱爲JavaScript互操作性,通常簡稱爲JavaScript互操作或 JS 互操作)訪問瀏覽器的完整功能。通過瀏覽器中的Web Assembly執行的.NET代碼在瀏覽器的JavaScript沙盒中運行,沙盒提供的保護可防禦客戶端計算機上的惡意操作。

Blazor Web Assembly應用生成並在瀏覽器中運行時:

已發佈應用的大小(其有效負載大小)是應用可用性的關鍵性能因素。大型應用需要相對較長的時間才能下載到瀏覽器,這會損害用戶體驗。Blazor Web Assembly優化有效負載大小,以縮短下載時間:

Blazor 託管模型

主要的Blazor託管模型在Web Assembly上的瀏覽器中運行客戶端。將Blazor應用、其依賴項以及.NET運行時下載到瀏覽器。應用將在瀏覽器線程中直接執行。UI 更新和事件處理在同一進程中進行。應用資產作爲靜態文件部署到可爲客戶端提供靜態內容的 Web 服務器或服務中。

如果創建了Blazor Web Assembly應用進行部署,但沒有後端ASP.NET Core應用來爲其文件提供服務,那麼該應用被稱爲獨立Blazor Web Assembly應用。如果創建了應用進行部署,但沒有後端應用來爲其文件提供服務,那麼該應用被稱爲託管的Blazor Web Assembly應用。託管的Blazor Web Assembly Client應用通常使用WebAPI調用或SignalR(結合使用ASP.NET Core SignalRBlazor)通過網絡與後端 Server 應用交互。

blazor.webassembly.js腳本由框架和句柄提供:

Blazor Web Assembly託管模型具有以下優點:

Blazor Web Assembly託管模型具有以下侷限性:

在傳統 Web 應用和單頁應用 (SPA) 之間選擇

Atwood 定律:任何能夠用 JavaScript 編寫的應用程序,最終必將用 JavaScript 編寫。- Jeff Atwood

目前可通過兩種通用方法來構建 Web 應用程序:在服務器上執行大部分應用程序邏輯的傳統 Web 應用程序,以及在 Web 瀏覽器中執行大部分用戶界面邏輯的單頁應用程序(SPA),後者主要使用WebAPI與 Web 服務器通信。也可以將兩種方法混合使用,最簡單的方法是在更大型的傳統 Web 應用程序中託管一個或多個豐富 SPA 類子應用程序。

何時使用傳統 Web 應用程序:

何時使用 SPA:

此外,SPA 框架還需要更強的體系結構和安全專業知識。相較於傳統 Web 應用程序,SPA 框架需要進行頻繁的更新和使用新框架,因此改動更大。相較於傳統 Web 應用,SPA 應用程序在配置自動化生成和部署過程以及利用部署選項(如容器)方面的難度更大。

使用 SPA 方法改進用戶體驗時必須權衡這些注意事項。

傳統 Web 應用程序、SPA 或 Blazor 應用之間進行選擇時要考慮的一些基本因素

FRR4CN

何時選擇傳統 Web 應用

應用程序的客戶端要求簡單,可能要求只讀

對許多 Web 應用程序而言,其大部分用戶的主要使用方式是隻讀。只讀(或以讀取爲主)應用程序往往比那些維護和操作大量狀態的應用程序簡單得多。例如,搜索引擎可能由一個帶有文本框的入口點和用於顯示搜索結果的第二頁組成。匿名用戶可以輕鬆提出請求,並且很少需要使用客戶端邏輯。同樣,一般而言,博客或內容管理系統中面向公衆的應用程序主要包含的內容與客戶端行爲關係不大。此類應用程序容易構建爲基於服務器的傳統 Web 應用程序,在 Web 服務器上執行邏輯,並呈現要在瀏覽器中顯示的 HTML。事實上,網站的每個獨特頁面都有自己的 URL,搜索引擎可以將其存爲書籤和編入索引(默認設置,無需將此功能添加爲應用程序的單獨功能),這也是此類情況的一個明顯優勢。

應用程序需在不支持 JavaScript 的瀏覽器中工作

如需在有限或不支持JavaScript的瀏覽器中工作的 Web 應用程序,則應使用傳統的 Web 應用工作流編寫(或至少可以回退到此類行爲)。SPA 需要客戶端JavaScript才能正常工作;如果沒有客戶端JavaScript,SPA 不是好的選擇。

團隊不熟悉 JavaScript 或 TypeScript 開發技術

如果團隊不熟悉JavaScriptTypeScript,但熟悉服務器端 Web 應用程序開發,那相較於 SPA,他們交付傳統 Web 應用的速度可能更快。除非以學習 SPA 編程爲目的,或需要 SPA 提供用戶體驗,否則對已經熟悉構建傳統 Web 應用的團隊而言,選擇傳統 Web 應用的工作效率更高。

何時選擇 SPA

應用程序必須公開具有許多功能的豐富用戶界面

SPA 可支持豐富客戶端功能,當用戶執行操作或在應用的各區域間導航時無需重新加載頁面。SPA 很少需要重新加載整個頁面,因此加載速度更快,可在後臺提取數據,並且對單個用戶操作的響應更快。SPA 支持增量更新,可保存尚未完成的窗體或文檔,而無需用戶單擊按鈕提交窗體。SPA 支持豐富的客戶端行爲,例如拖放,比傳統應用程序更容易操作。可以將 SPA 設計爲在斷開連接的模式下運行,對客戶端模型進行更新,並在重新建立連接後將更新最終同步回服務器。如果應用要求包括豐富的功能,且超出了典型 HTML 窗體提供的功能,則選擇 SPA 樣式應用程序。

通常,SPA 需要實現內置於傳統 Web 應用中的功能,例如在反映當前操作的地址欄中顯示有意義的 URL(並允許用戶將此 URL 存爲書籤或對其進行深層鏈接以便返回此 URL)。SPA 還應允許用戶使用瀏覽器的後退和前進按鈕尋找用戶意料之中的結果。

團隊熟悉 JavaScript 和 / 或 TypeScript 開發

編寫 SPA 需要熟悉JavaScriptTypeScript以及客戶端編程技術和庫。團隊應有能力像使用Angular一樣使用 SPA 框架編寫新式JavaScript

參考 - SPA 框架

應用程序已爲其他(內部或公共)客戶端公開 API

如果已提供一個Web API供其他客戶端使用,則相較於在服務器端窗體中複製邏輯,創建一個利用這些APISPA實現更加容易。用戶與應用程序交互時,SPA廣泛使用Web API來查詢和更新數據。

何時選擇 Blazor

應用程序必須公開豐富用戶界面

與基於JavaScript的 SPA 一樣,Blazor應用程序可以支持豐富的客戶端行爲,而無需重載頁面。這些應用程序對用戶的響應更快,僅獲取響應給定用戶交互所需的數據(或 HTML)。如果設計得當,可以將服務器端Blazor應用配置爲以客戶端Blazor應用的形式運行,只需在此功能受支持後對它進行稍加更改即可。

與使用 JavaScript 或 TypeScript 開發相比,團隊更喜歡使用. NET 開發

與使用JavaScriptTypeScript等客戶端語言相比,許多使用. NET 和Razor的開發人員的工作效率更高。由於已經使用. NET 開發了應用程序的服務器端,因此,使用Blazor可以確保團隊中的每名. NET 開發人員都可以理解,並可能會生成應用程序前端的行爲。

Blazor Server

運行時停留在服務器上並處理:

Blazor Server用於與瀏覽器通信的連接還用於處理JavaScript互操作調用。

JavaScript 互操作

對於需要第三方JavaScript庫和訪問瀏覽器 API 的應用,組件與JavaScript進行互操作。組件能夠使用JavaScript能夠使用的任何庫或 API。C# 代碼可調用到JavaScript代碼,而JavaScript代碼可調用到 C# 代碼。

在 ASP.NET Core Blazor 中從. NET 方法調用 JavaScript 函數

https://docs.microsoft.com/zh-cn/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-5.0

從 ASP.NET Core Blazor 中的 JavaScript 函數調用. NET 方法

https://docs.microsoft.com/zh-cn/aspnet/core/blazor/call-dotnet-from-javascript?view=aspnetcore-5.0

Blazor 支持的平臺

Iy1Ukz

†最新指的是瀏覽器的最新版本。

Blazor 模板選項

創建我的第一個 Blazor 應用

1. 先準備 ".NET SDK (Software Development Kit)" 環境。

如果之前沒有安裝的先安裝這個 SDK:

dotnet-sdk-5.0.202-win-x64.exe

如果已經安裝過了,檢查下當前版本:

dotnet --version

2. 根據 Blazor 項目模板創建應用

1) 命令行方式創建

dotnet new blazorserver -o BlazorApp --no-https
dotnet new blazorwasm -o BlazorApp --no-https

創建成功之後,會自動打開項目解決方案。

3. 運行應用

1) 命令行方式創建

如果通過命令行方式創建,運行應用只需要執行:

dotnet watch run

運行起來之後,會看到瀏覽器彈出應用首頁。

如果要退出運行,只需要執行如下命令即可:

Ctrl + C

2) Visual Studio 方式創建

Visual Studio裏面運行就很簡單了,直接點運行BlazorApp或者Ctrl + F5即可。

默認會打開一個終端控制檯界面,用來顯示 Console 日誌。

運行起來之後,會看到瀏覽器彈出應用首頁。

4. 項目結構

5. 認識首頁及組件

我們看到Pages/Index.razor這個主頁。

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

這裏已經有了SurveyPrompt這樣一個組件,同時它有一個入參Title可以定製。

6. 查看子組件計數器

打開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++;
    }
}

我們可以從代碼看到,頂部@page "/counter"實際上這個頁面組件的目錄,當我們切換到它時,路徑也會變化。

每次點擊Click me按鈕的時候,就會從onclick事件去找到IncrementCount這個函數,在這個函數中,我們把currentCount做了加1,這時候,Current count的值會跟着刷新,可以看出只要綁定好了數據,它就會幫我們自動去更新界面顯示了,還是很方便。

7. 在首頁添加子組件計數器

打開Pages/Index.razor,我們在末尾追加Counter即可。

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

<Counter />

這時候,我們查看頁面就已經可以看到它了。

8. 修改組件添加屬性並使用

接下來,我們打開Pages/Counter.razor,我們給這個組件添加一個參數屬性IncrementAmount,默認值是1, 這樣我們可以從外部傳遞值進來修改它,並且我們讓currentCount不再是繼續加1了,而是改成加IncrementAmount的值,這樣我們就可以控制每次累加的幅度。

@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;

    [Parameter]
    public int IncrementAmount { get; set; } = 1;

    private void IncrementCount()
    {
        currentCount += IncrementAmount;
    }
}

然後,我們回到Pages/Index.razor,在Counter組件上給他傳遞IncrementAmount的值進來。

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

<Counter IncrementAmount="10" />

這時候,界面會自動重載,這時候,我們每次點擊Click me,這個計時器組件就會加10了,哈哈,是不是很簡單。

生成 Blazor 待辦事項列表應用

1. 先準備 ".NET SDK (Software Development Kit)" 環境。

如果之前沒有安裝的先安裝這個 SDK:

dotnet-sdk-5.0.202-win-x64.exe

如果已經安裝過了,檢查下當前版本:

dotnet --version

2. 創建待辦事項列表 Blazor 應用

dotnet new blazorserver -o TodoList --no-https

通過DOTNET-CLI腳本的New命令,新建一個blazorserver項目模板,輸出目錄命名爲TodoList,同時不需要HTTPS的支持。

3. 添加名爲 “Todo” 的 Blazor 組件

cd TodoList

先切換到TodoList項目文件夾中。

dotnet new razorcomponent -n Todo -o Pages

然後,通過DOTNET-CLI腳本的New命令,輸出目錄爲Pages,新建名爲Todorazorcomponent組件。

其中-n全稱爲--name,用來指定創建的名稱,-o全稱爲--output,用來指定在這個目錄進行創建。

Razor組件文件名要求首字母大寫。打開Pages文件夾,確認Todo組件文件名以大寫字母 T 開頭。文件名應爲Todo.razor

將在項目文件夾的Pages目錄中,新建得到一個Todo.razor文件。

接下來,我們需要在Todo.razor文件頂部添加針對該文件組件的路由位置。

@page "/todo"

4. 將 “Todo” 的 Blazor 組件添加到左側導航

位於Shared文件夾的NavMenu.razor組件是控制左側導航的,我們需要將 “Todo” 的 Blazor 組件添加到左側導航中。

NavMenu.razor組件中,找到ul元素下的li節點,參考前面的例子,新建屬於Todo組件的導航位置。

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        ...
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="todo">
                <span class="oi oi-list-rich" aria-hidden="true"></span> ToDoList
            </NavLink>
        </li>
    </ul>
</div>

這裏我們需要注意的幾個關鍵點是,NavLinkhref需要填寫組件的路由位置,其中span元素是菜單圖標,緊跟着它的就是菜單名稱,這裏我們用ToDoList來作爲菜單名稱。

保存之後,我們通過執行run命令來運行,查看導航效果。

dotnet watch run

5. 添加 “TodoItem” 來存儲待辦事項數據。

這裏一個小插曲就是爲了更好的寫出TodoItem.cs這個模型類,我遇到了兩個不錯的 VSC 插件,這裏就順帶記錄一下。

這兩個插件,搜索C#這個關鍵詞就可以看到了,基本上排在前面。

有了它們,我們創建TodoItem模型類就如虎添翼了。

在項目的Data文件夾中,我們右鍵,選擇New C# Class,輸入TodoItem,然後回車即可。

然後我們就自動完成,得到了一個基礎的空的TodoItem.cs模型類,它的namespace都是已經處理好了,我覺得比手寫強吧。

接下里,我們往TodoItem.cs模型類中添加兩個屬性(最好是走prop命令來新建),一個是Title來存儲待辦事項的標題,一個是IsDone來標記是否已完成該事項。

接下來,爲了將來更好的閱讀這個模型,我們養成一個好習慣,給對應的模型和字段都添加好註釋,這時候C# XML Documentation Comments這個 VSC 插件就要派上用場了,通過在所需要註釋代碼的開頭位置,輸入///然後回車即可。

namespace TodoList.Data
{
    /// <summary>
    /// 待辦事項
    /// </summary>
    public class TodoItem
    {
        /// <summary>
        /// 事項名稱
        /// </summary>
        /// <value></value>
        public string Title { get; set; }

        /// <summary>
        /// 事項是否已完成
        /// </summary>
        /// <value></value>
        public bool IsDone { get; set; }
    }
}

參考

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/SGCunHaUZlwWJ9xpVnM7zQ