Window.localStorage
只讀的localStorage 屬性允許你訪問一個Document 源(origin)的對象 Storage;存儲的數據將保存在瀏覽器會話中。
存儲在 localStorage 的數據可以長期保留
localStorage 中的鍵值對總是以字符串的形式存儲。 (需要注意, 和js對象相比, 鍵值對總是以字符串的形式存儲意味着數值類型會自動轉化為字符串類型).
瀏覽器兼容性
桌面:
Chrome,
Edge,
Firefox,
Internet Explorer,
Opera,
Safari
移動端:
WebView Android,
Chrome Android,
Firefox for Android,
Opera Android,
Safari on iOS,
Samsung Internet
Blazor WebAssembly
Blazor WebAssembly 用於使用 .NET 生成交互式客戶端 Web 應用。 Blazor WebAssembly 使用無插件或將代碼重新編譯為其他語言的開放式 Web 標准。 Blazor WebAssembly 適用於所有新式 Web 瀏覽器,包括移動瀏覽器。
通過 WebAssembly(縮寫為 wasm),可在 Web 瀏覽器內運行 .NET 代碼。 WebAssembly 是針對快速下載和最大執行速度優化的壓縮字節碼格式。 WebAssembly 是開放的 Web 標准,支持用於無插件的 Web 瀏覽器。
WebAssembly 代碼可通過 JavaScript(稱為 JavaScript 互操作性,通常簡稱為 JavaScript 互操作或 JS 互操作)訪問瀏覽器的完整功能 。 通過瀏覽器中的 WebAssembly 執行的 .NET 代碼在瀏覽器的 JavaScript 沙盒中運行,沙盒提供的保護可防御客戶端計算機上的惡意操作。
當 Blazor WebAssembly 應用生成並在瀏覽器中運行時:
- C# 代碼文件和 Razor 文件將被編譯為 .NET 程序集。
- 該程序集和 .NET 運行時將被下載到瀏覽器。
- Blazor WebAssembly 啟動 .NET 運行時,並配置運行時,以為應用加載程序集。 Blazor WebAssembly 運行時使用 JavaScript 互操作來處理 DOM 操作和瀏覽器 API 調用。
已發布應用的大小(其有效負載大小)是應用可用性的關鍵性能因素。 大型應用需要相對較長的時間才能下載到瀏覽器,這會損害用戶體驗。 Blazor WebAssembly 優化有效負載大小,以縮短下載時間:
- 在中間語言 (IL) 裁邊器發布應用時,會從應用刪除未使用的代碼。
- 壓縮 HTTP 響應。
- .NET 運行時和程序集緩存在瀏覽器中。
漸進式 Web 應用程序 (PWA)
Blazor 漸進式 Web 應用 (PWA) 是一種單頁應用程序 (SPA),它使用新式瀏覽器 API 和功能以表現得如桌面應用。
Blazor WebAssembly 是基於標准的客戶端 Web 應用平台,因此它可以使用任何瀏覽器 API,包括以下功能所需的 PWA API:
- 脫機工作並即時加載(不受網絡速度影響)。
- 在自己的應用窗口中運行,而不僅僅是在瀏覽器窗口中運行。
- 從主機操作系統的開始菜單、擴展塢或主屏幕啟動。
- 從后端服務器接收推送通知,即使用戶沒有在使用該應用。
- 在后台自動更新。
使用“漸進式”一詞來描述這些應用的原因如下:
- 用戶可能先是在其網絡瀏覽器中發現應用並使用它,就像任何其他單頁應用程序一樣。
- 過了一段時間后,用戶進而將其安裝到操作系統中並啟用推送通知。
實現
這次主要以大家談論比較多的 WASM PWA 為例子,其實 wasm 或 ssr 工程都是可以的完整運行的.
1.新建工程n04LocalStorage_wasm
新建項目選擇 Blazor WebAssembly 應用
,請選中 漸進式 Web 應用
復選框, 工程命名為 'n04LocalStorage_wasm'
然后右鍵工程, 管理Nugget程序包
添加Blazored.LocalStorage
庫到工程中.
或者.NET CLI
dotnet new blazorwasm -o n04LocalStorage_wasm --pwa
dotnet add n04LocalStorage_wasm package Blazored.LocalStorage
dotnet sln add n04LocalStorage_wasm/n04LocalStorage_wasm.csproj
ssr參考
dotnet new blazorserver -o n04LocalStorage
dotnet add n04LocalStorage package Blazored.LocalStorage
dotnet sln add n04LocalStorage/n04LocalStorage.csproj
話不多說,直接上簡單測試代碼
1. 添加服務
Program.cs
using Blazored.LocalStorage;
builder.Services.AddBlazoredLocalStorage();
2. Index.razor
注入服務,編寫兩個方法
@using Blazored.LocalStorage;
@code{
[Inject] ILocalStorageService? localStore { get; set; }
const string noteKey = "note";
string? noteContent;
public async void UpdateLocalStorage()
{
await localStore!.SetItemAsync(noteKey, noteContent);
}
public async void ClearLocalStorage()
{
noteContent = "";
await localStore!.ClearAsync();
}
}
3. 頁面使用js需要在OnAfterRenderAsync里執行, 如果在不對的生命周期里面執行,會有這句報錯提示,剛開始學blazor的同學應該都有遇到過
InvalidOperationException: JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendered. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.
4. 讀取LocalStorage的對象到noteContent,然后刷新頁面.
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
noteContent = await localStore!.GetItemAsync<string>(noteKey);
StateHasChanged();
}
}
5. 文本域綁定變量,保存到LocalStorage
<textarea @bind="noteContent" />
<br />
<button @onclick="UpdateLocalStorage">Save</button>
<button @onclick="ClearLocalStorage">Clear</button>
瀏覽器按F12,查看應用
,本地存儲空間,每次保存按下,觀察效果.
重啟程序,看看是否能保持上次寫入的文字
6.改造 FetchData
WeatherForecast類定義
public class WeatherForecast
{
public DateTime Date { get; set; }=DateTime.Now;
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; } = "陽光明媚";
public string? SkyColor { get; set; }
}
常規CRUD操作
[Inject] ILocalStorageService? localStore { get; set; }
private List<WeatherForecast>? forecasts;
private WeatherForecast? one = new WeatherForecast();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
forecasts = await localStore!.GetItemAsync<List<WeatherForecast>>("forecasts");
if (forecasts == null)
{
forecasts = new List<WeatherForecast>();
await localStore!.SetItemAsync("forecasts", forecasts);
}
StateHasChanged();
}
}
async void Add()
{
forecasts!.Add(one!);
one = new WeatherForecast();
await localStore!.SetItemAsync("forecasts", forecasts);
}
async void Edit()
{
await localStore!.SetItemAsync("forecasts", forecasts);
}
async void Delete(WeatherForecast weather)
{
forecasts!.Remove(weather);
await localStore!.SetItemAsync("forecasts", forecasts);
}
async void Clear()
{
forecasts!.Clear();
await localStore!.ClearAsync();
}
頁面
<div style="background-color :lightblue">
<p>
日期
<input type="datetime-local" @bind-value="one!.Date" />
</p>
<p>
溫度
<input type="number" @bind-value="one!.TemperatureC" />
</p>
<p>
<input @bind-value="one!.Summary" />
</p>
<p>
<input type="color" @bind-value="one!.SkyColor" />
</p>
<button @onclick="Add" class="btn btn-primary">新添</button>
</div>
@if (forecasts == null)
{
<p><em>無數據...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
<th>SkyColor</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>
<input @bind-value="forecast.Date" />
</td>
<td>
<input @bind-value="forecast.TemperatureC" />
</td>
<td>@forecast.TemperatureF</td>
<td>
<input @bind-value="forecast.Summary" />
</td>
<td>
<input type="color" @bind-value="forecast.SkyColor" />
</td>
<td>
<button @onclick="Edit" class="btn btn-primary">編輯</button>
</td>
<td>
<button @onclick="(()=>Delete(forecast))" class="btn btn-warning">刪除</button>
</td>
</tr>
}
</tbody>
</table>
<button @onclick="Clear" class="btn btn-danger">清空</button>
}
執行看看效果吧
7. 把頁面弄到手機上試試, 發送到桌面還可以假裝成APP :->
Properties , launchSettings.json
修改這句
"applicationUrl": "https://localhost:7286;http://localhost:5274;https://0.0.0.0:7286;http://0.0.0.0:5274",
手機訪問 http://192.168.1.103:5274/
192.168.1.103替換為你機器ip
8. 離線運行PWA
據我測試,需要部署到域名, demo https://testbrpwa.app1.es/
參考資料 :
PWA 網站離線訪問 https://www.jianshu.com/p/f10e72797d25
PWA離線化技術介紹 https://juejin.cn/post/6990937987697606669
原文鏈接:https://www.cnblogs.com/densen2014/p/16133343.html
項目源碼
關聯項目
FreeSql QQ群:4336577(已滿)、8578575(已滿)、52508226(在線)
BA & Blazor QQ群:795206915、675147445
知識共享許可協議
本作品采用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名AlexChow(包含鏈接: https://github.com/densen2014 ),不得用於商業目的,基於本文修改后的作品務必以相同的許可發布。如有任何疑問,請與我聯系 。