原文链接:https://www.cnblogs.com/densen2014/p/16133343.html

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

项目源码

Github | Gitee

关联项目

FreeSql QQ群:4336577(已满)、8578575(已满)、52508226(在线)

BA & Blazor QQ群:795206915、675147445

知识共享许可协议

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名AlexChow(包含链接: https://github.com/densen2014 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

AlexChow

今日头条 | 博客园 | 知乎 | Gitee | GitHub

Blazor WebAssembly 渐进式 Web 应用程序 (PWA) 使用 LocalStorage 离线处理数据的更多相关文章

  1. PWA 渐进式Web应用程序 - 解释

    想象一下,如果一个网站上所有的功能都能够作为一个移动应用程序为用户所用——任何设备上都可以使用.可接收所有的通知.离线模式可用,为了实现这个愿景,2015年,谷歌创造了渐进式Web应用程序(PWA). ...

  2. (转)PWA(Progressive Web App)渐进式Web应用程序

    PWA 编辑 讨论 PWA(Progressive Web App)是一种理念,使用多种技术来增强web app的功能,可以让网站的体验变得更好,能够模拟一些原生功能,比如通知推送.在移动端利用标准化 ...

  3. 开发一个渐进式Web应用程序(PWA)前都需要了解什么?

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://dzone.com/articles/how-to-build-a-progres ...

  4. 使用 React.js 的渐进式 Web 应用程序:第 1 部分 - 介绍

      使用 React.js 的渐进式 Web 应用程序:第 1 部分 - 介绍 使用 React.js 的渐进式 Web 应用程序:第 1 部分 - 介绍 来自译者 markzhai:大家也知道最近 ...

  5. 创建一个离线优先,数据驱动的渐进式 Web 应用程序

    原文地址:Build an offline-first, data-driven PWA 译文出自:我的个人博客 概述 在本文中,您将学习如何使用 Workbox 和 IndexedDB 创建离线优先 ...

  6. 渐进式Web应用(PWA)入门教程(上)

    最近关于渐进式Web应用有好多讨论,有一些人还在质疑渐进式Web应用是否就是移动端未来. 但在这篇文章中我并不会将渐进式APP和原生的APP进行比较,但有一点是可以肯定的,这两种APP的目标都是使用户 ...

  7. 渐进式Web应用(PWA)入门教程(下)

    上篇文章我们对渐进式Web应用(PWA)做了一些基本的介绍. 渐进式Web应用(PWA)入门教程(上) 在这一节中,我们将介绍PWA的原理是什么,它是如何开始工作的. 第一步:使用HTTPS 渐进式W ...

  8. 渐进式Web应用程序的深入概述

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://www.grapecity.com.cn/blogs/wijmo-depth-ove ...

  9. 渐进式Web应用(PWA)

    什么是渐进式Web应用? 渐进式Web应用是一种全新的Web技术,让Web应用和原生APP的体验相近或一致. 渐进式Web应用它可以横跨Web技术及Native APP开发的解决方案,对于开发者的优势 ...

随机推荐

  1. ybt1184:明明的随机数

    [题目描述] 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数 ...

  2. JAVA 线上问题排查方法

    CPU 磁盘 内存 GC问题 网络 线上故障主要会包括cpu.磁盘.内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍. 同时例如jstack.jma ...

  3. LFS系列镜像在阿里云镜像站首发上线

    LFS镜像 镜像详情页: https://developer.aliyun.com/mirror/lfs Linux From Scratch (LFS) 是一个项目,它为您提供完全从源代码构建您自己 ...

  4. linux 下载源

    Cenos7 Nginx [nginx-stable]name=nginx stable repobaseurl=http://nginx.org/packages/centos/$releaseve ...

  5. Blazor 002 : 一种开历史倒车的UI描述语言 -- Razor

    Razor是一门相当怪异丑陋的标记语言,但在实际使用中却十分高效灵活.本文主要介绍了Razor是什么,以及Razor引擎的一些浅薄的背后机理. 写文章前我本想一口气把Razor的基本语法,以及Blaz ...

  6. web自动化之定位

    UI自动化必不可少的操作--元素定位 8大基础定位 driver.find_element_by_id() # id定位 driver.find_element_by_name() # name定位 ...

  7. 压测工具 jmeter入门教程及汉化修改

    Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件.相比Loadrunner而言,JMeter小巧轻便且免费,逐渐成为了主流的性能测试工具,是每个测试人员都必须要掌握的工 ...

  8. 『忘了再学』Shell基础 — 4、Bash基本功能(history命令)

    目录 1.history历史命令 2.设置命令历史记录的条数 3.清空历史命令 4.历史命令的调用 5.命令与文件的补全 在Linux系统中默认的Shell就是Bourne-AgainShell(简称 ...

  9. Notion-douan:搭建自己的阅读清单

    前言 交完论文盲审稿,终于从接近一年的实习.秋招和论文的忙碌中闲下来. 在复盘秋招的时候发现自己虽然看过不少书,但缺少整理和思考,所以想趁这个机会梳理一下自己的阅读习惯,希望以后再读新的东西可以更系统 ...

  10. java实现稀疏矩阵的压缩与解压

    任务要求 把棋盘当作一个稀疏矩阵,0表示没棋,1表示黑棋,2表示蓝棋. 把该稀疏矩阵压缩以三元组形式表示并以文件形式保存,再写另一个程序读取文件中的信息把压缩后的三元组还原成原来的稀疏矩阵. 其中三元 ...