一. 前言
Blazor 的整體介紹以及特點與優勢,建議翻閱 Blazor 介紹。
Blazor 是一個可是使用 .NET/C# 來編寫交互式客戶端的 Web UI 框架,在官網有一句話概括 “Build client web apps with C#”。在 Blazor 里面有三個比較重要的概念:
- Components
- Blazor WebAssembly
- Blazor Server
Components 翻譯過來就是組件,是指 UI 元素,例如頁面、對話框或數據輸入窗體。Blazor 應用就是由各種各樣的組件搭建起來的,類似於 Vue、React、Angular等Js組件。組件的文件名 通常以 .razor
結尾。
Blazor Server 將組件呈現邏輯從 UI 更新的應用方式中分離出來。 Blazor Server 在 ASP.NET Core 應用中添加了對在服務器上托管 Razor 組件的支持。 可通過 SignalR 連接處理 UI 更新。運行時處理從瀏覽器向服務器發送 UI 事件,並在運行組件后,將服務器發送的 UI 更新並重新應用到瀏覽器。Blazor Server 用於與瀏覽器通信的連接還用於處理 JavaScript 互操作調用。
Blazor WebAssembly 是一個單頁應用(SPA)框架,可用它通過 .NET 生成交互式客戶端 Web 應用。 Blazor WebAssembly 使用開放的 Web 標准(沒有插件或代碼轉換),適用於移動瀏覽器等各種新式 Web 瀏覽器。通過 WebAssembly(縮寫為 wasm),可在 Web 瀏覽器內運行 .NET 代碼。 WebAssembly 是針對快速下載和最大執行速度優化的壓縮字節碼格式。 WebAssembly 是開放的 Web 標准,支持無插件用於 Web 瀏覽器。WebAssembly 代碼可通過 JavaScript JavaScript 互操作訪問瀏覽器的完整功能。 通過瀏覽器中的 WebAssembly 執行的 .NET 代碼在瀏覽器的 JavaScript 沙盒中運行,沙盒提供的保護可防御在客戶端計算機上的惡意操作(這點無法像ActiveX那樣了)。
以上內容 摘自官方文檔
2019 年 9 月 Blazor 發布了 0.1.0 版本,后面發布了 Blazor Server 正式版,但是 Blazor WebAssembly 一直還在預覽版中,Blazor Server 雖然實現了 C# 來編寫界面,但是應用UI更新,需要通過UI事件,經過 SignalR 與服務端通信執行業務代碼來應用UI更新。最令我感興趣的是 Blazor WebAssembly,期待已久 ,實現了開放 Web 標准 WebAssembly ,讓在客戶端瀏覽器運行C#代碼成為現實,我覺得在這一點,微軟走在了前列,雖然大家可能會用 Silverlight 的黑歷史來吐槽微軟,但是這次不一樣,WebAssembly 不是微軟自家定的。雖然目前它還很年輕,但是我對它還是非常期待與看好。
二. Blazor Server 與 Blazor WebAssembly 對比
1.PWA的支持
Server 不支持,Wasm 支持
2.更新UI流程不同
(1)Blazor Server 在頁面加載時,會創建一個 WebSocket 連接(通過 SignalR),會一直發送心跳包來檢測連接是否健康。
心跳包:
Blazor Server 執行業務代碼邏輯是通過 SignalR 發送事件到服務端,服務端執行代碼,再返回結果,根據返回的數據渲染UI,應用更新,通過下圖可以看到。
(2)Blazor WebAssembly 則不同,無需通過服務端來執行C#代碼,直接在瀏覽器執行,來更新UI,獲取數據。類似於 Ajax ,通過調用 HTTP Api 來獲取數據。
這里需要說明的是,VS里面打斷點依然能被正常捕獲,是因為 Blazor 框架與 VS 進行了通信來實現 Debug,不然要是不能 Debug 問題可就大了。
在VS中一直F10也會進入到一個JS文件
雖然都能被Debug,但是流程實則完全不一樣。
三. 建立第一個 Blazor WebAssembly 應用
1.必備條件
因為 Blazor WebAssembly 是在 2020.05.19 才發布正式版的,所以 Visual Studio 2019 需要更新到新版 >=16.6(macOS >=8.6)
2.創建應用
第一步,選擇 Blazor App 模板
第二步,選擇 Blazor WebAssembly
建立好的項目具有以下目錄結構
運行項目,可以看到加載了很多熟悉的 dll
其中列表頁面,通過 HttpClient 訪問了一個靜態的 json 文件
四. 初體驗
1.運行淺析
入口點在 wwwroot/index.html 通過 blazor.webassembly.js 下載 .NET 運行時、應用程序和依賴。這個js文件並不包含在項目文件中,是由 Microsoft.AspNetCore.Components.WebAssembly.Build
工具包提供的,編譯生成的時候會輸出到目標目錄:
2.實現簡單邏輯
簡單的改了 Counter 的代碼,成了一個 Guid 生成器,這點體驗還是很好的,直接用C#代碼編寫邏輯而不是JavaScript,而且是本地運行直接運行C#代碼,不需要 Blazor Server 這樣的通過 SignalR 通信。
@page "/counter"
<h1>GUID 生成器</h1>
<div class="row">
<div class="col-2">
<input class="form-control" type="text" value="@_guidValue"/>
</div>
<div class="col-10">
<button class="btn btn-primary" @onclick="GenerateGuid">生 成</button>
</div>
</div>
@code {
private Guid? _guidValue;
private void GenerateGuid()
{
_guidValue = Guid.NewGuid();
}
}
3.與JS的互操作
上面實現了GUID生成器,但是每次生成了都需要自己去輸入框復制,不方便,現在實現一個自動復制到剪貼板的功能。
此功能無法百分百通過C#代碼來實現,需要與JS進行交互。
先編寫 JS:
window.clipboardCopy = {
copyText: function (text) {
navigator.clipboard.writeText(text).then(function () {
alert("Copied to clipboard!");
})
.catch(function (error) {
alert(error);
});
}
};
該JS放置的位置,可以寫在Js文件中,在Index.html中應用,也可以直接寫在 Index.html中。
然后在 Razor 組件中注入 JSRuntime,並調用該JS:
@page "/counter"
@inject IJSRuntime JsRuntime
<h1>GUID 生成器</h1>
<div class="row">
<div class="col-2">
<input class="form-control" type="text" value="@_guidValue" />
</div>
<div class="col-10">
<button class="btn btn-primary" @onclick="GenerateGuid">生 成</button>
<button class="btn btn-danger" @onclick="CopyTextToClipboard">復制到剪貼板</button>
</div>
</div>
@code {
private Guid? _guidValue;
private void GenerateGuid()
{
_guidValue = Guid.NewGuid();
}
private async Task CopyTextToClipboard()
{
await JsRuntime.InvokeVoidAsync("clipboardCopy.copyText", _guidValue);
}
}
運行:
小技巧:通過 dotnet watch run
命令可以獲得更快樂的開發體驗。
五.結束
Blazor WebAssembly 的初次嘗試到此就結束了,一直在等正式版,到現在終於等到了,我也是才是學習它,后面陸續會出一些分享文章,希望可以與大家一起學習進步。