Blazor能否实现类似HTML的LocalStorage本地存储功能?
Blazor中实现HTML5 Web Storage功能
当然可以!Blazor 完全支持通过**JavaScript 互操作(JS Interop)**来访问浏览器的 localStorage 和 sessionStorage,实现和你提供的 HTML 示例完全相同的持久化数据功能。下面是具体的实现方案:
完整实现示例
我们可以直接通过 Blazor 的 IJSRuntime 调用浏览器的 localStorage API,不需要额外的独立 JS 文件(当然也可以封装成 JS 函数,看个人偏好)。
1. 创建 Blazor 组件(Razor 文件)
创建一个名为 StorageCounter.razor 的组件,代码如下:
@page "/storage-counter" @inject IJSRuntime JSRuntime <h3>点击计数器(持久化版)</h3> @if (!isStorageSupported) { <div class="alert alert-warning">抱歉,你的浏览器不支持 Web Storage 功能...</div> } else { <p><button @onclick="IncrementCounter" class="btn btn-primary">点击我!</button></p> <div>你已经点击了按钮 @clickCount 次。</div> <p>关闭浏览器标签页(或窗口)后再次打开,计数器会继续累加,不会重置。</p> } @code { private int clickCount = 0; private bool isStorageSupported = true; protected override async Task OnInitializedAsync() { // 先检查浏览器是否支持 Web Storage isStorageSupported = await JSRuntime.InvokeAsync<bool>("() => typeof(Storage) !== 'undefined'"); if (isStorageSupported) { // 从 localStorage 加载保存的计数 var storedCount = await JSRuntime.InvokeAsync<string?>("localStorage.getItem", "clickcount"); if (int.TryParse(storedCount, out int count)) { clickCount = count; } } } private async Task IncrementCounter() { if (isStorageSupported) { clickCount++; // 将更新后的计数保存到 localStorage await JSRuntime.InvokeVoidAsync("localStorage.setItem", "clickcount", clickCount.ToString()); } } }
2. 代码说明
IJSRuntime注入:Blazor 通过这个服务实现与浏览器 JavaScript 的交互。- 初始化时加载数据:在组件初始化方法
OnInitializedAsync中,我们先检查浏览器是否支持 Web Storage,然后从localStorage读取之前保存的计数。 - 点击事件处理:点击按钮时,累加计数并将新值保存到
localStorage。 - 浏览器兼容性处理:如果浏览器不支持 Web Storage,会显示提示信息,和你的 HTML 示例逻辑一致。
可选:封装成 JavaScript 函数
如果你更倾向于像原示例那样使用独立的 JS 函数,可以在 wwwroot/index.html(Blazor WebAssembly)或 Pages/_Host.cshtml(Blazor Server)中添加以下脚本:
<script> // 检查 Storage 支持 function isStorageSupported() { return typeof(Storage) !== "undefined"; } // 获取保存的点击计数 function getClickCount() { return localStorage.clickcount || 0; } // 保存点击计数 function setClickCount(count) { localStorage.clickcount = count; } </script>
然后修改组件中的代码,调用这些封装好的函数:
@code { // ... 其他代码不变 ... protected override async Task OnInitializedAsync() { isStorageSupported = await JSRuntime.InvokeAsync<bool>("isStorageSupported"); if (isStorageSupported) { var storedCount = await JSRuntime.InvokeAsync<string>("getClickCount"); if (int.TryParse(storedCount, out int count)) { clickCount = count; } } } private async Task IncrementCounter() { if (isStorageSupported) { clickCount++; await JSRuntime.InvokeVoidAsync("setClickCount", clickCount.ToString()); } } }
注意事项
- Blazor Server vs WebAssembly:上述代码在两种托管模型下都能正常工作,因为
localStorage是浏览器端的 API,JS Interop 会直接在客户端执行相关操作。 - 数据类型:
localStorage只能存储字符串,所以需要将数值类型转换为字符串再保存,读取时再转换回来。 - 隐私模式:部分浏览器在隐私模式下会禁用
localStorage,此时isStorageSupported会返回true,但读写操作会抛出错误,建议在生产环境中添加 try-catch 块处理这类异常。
内容的提问来源于stack exchange,提问作者MaxB
相关产品推荐
相关产品推荐

