
前端UI组件设计系统【免费下载链接】ant-design-blazor基于 Ant Design 与 Blazor 的前端组件库。让开发者解放生产力实现更大价值。项目地址https://gitcode.com/ant-design-blazor/ant-design-blazor点击查看免费下载在填写长表单时用户常因误关页面、刷新或会话过期而丢失已输入的数据。ant-design-blazor 的 ExperimentalDraft草稿组件提供了一套开箱即用的解决方案通过DraftMonitor组件与Form组合表单数据一旦发生变化即自动延迟保存到浏览器localStorage用户重新打开页面时可一键恢复未完成的草稿。读完本文你将掌握如何在任意Form上接入草稿自动保存、配置延迟时长与恢复模式、使用版本控制防止恢复过期数据以及通过自定义存储提供者将草稿落库到任意后端。设计思想组合而非继承为任意表单「无侵入」加装草稿能力DraftMonitor的核心设计是组合composition而非继承inheritance。它不需要你的表单继承任何特定基类也不需要改造表单内部逻辑而是作为一个独立的监视组件包裹在表单旁边通过Data/DataChanged这一对参数与表单数据建立双向关联表单数据写入Data组件用JsonSerializer序列化后与上一次快照对比检测到变化即触发延迟保存组件恢复草稿时通过DataChanged回调或OnUpdate回调把数据写回表单。这意味着任何Form、任何 POCO 数据模型都可以获得草稿能力官方演示见 FormIntegration.razor 与配套说明文档 form-integration.md。完整工作流程一次典型的表单草稿生命周期如下首次渲染DraftMonitor在OnAfterRenderAsync首帧检查本地存储中是否存在该 Key 对应的草稿内部调用HasDraftAsync存在草稿根据恢复模式弹出确认框、自动恢复或忽略LoadDraftAsync读取并做版本校验编辑过程每次OnParametersSetAsync检测到Data序列化结果变化调用SaveDraftAsync启动一次防抖延迟保存默认延迟 1000ms提交成功调用ClearDraftAsync()删除本地草稿避免下次访问误恢复已提交数据。快速接入在 Form 上启用草稿自动保存以下代码改编自官方演示 FormIntegration.razor展示了最典型的接入方式一个用户注册表单包含用户名、邮箱、密码、简介、记住我五个字段。DraftMonitor TDataFormModel refdraftMonitor Datamodel DataChangedOnModelChanged OptionsdraftOptions OnRecoveredOnDraftRecovered OnDeletedOnDraftDeleted / Form Modelmodel OnFinishOnFinish OnFinishFailedOnFinishFailed LabelColSpan8 WrapperColSpan16 FormItem LabelUsername Input bind-Valuecontext.Username / /FormItem FormItem LabelEmail Input bind-Valuecontext.Email / /FormItem FormItem LabelPassword InputPassword bind-Valuecontext.Password / /FormItem FormItem LabelBio TextArea bind-Valuecontext.Bio Rows4 / /FormItem FormItem LabelRemember me WrapperColOffset8 WrapperColSpan16 Checkbox bind-Valuecontext.RememberMeRemember me/Checkbox /FormItem FormItem WrapperColOffset8 WrapperColSpan16 Space SpaceItem Button TypeButtonType.Primary HtmlTypesubmitSubmit/Button /SpaceItem SpaceItem Button OnClickClearDraftClear Draft/Button /SpaceItem SpaceItem Button OnClickResetReset/Button /SpaceItem /Space /FormItem /Form对应的code代码块含数据模型、配置与事件处理public class FormModel { [Required(ErrorMessage Please enter username)] public string Username { get; set; } [Required(ErrorMessage Please enter email)] [EmailAddress(ErrorMessage Please enter a valid email address)] public string Email { get; set; } [Required(ErrorMessage Please enter password)] [MinLength(6, ErrorMessage Password must be at least 6 characters)] public string Password { get; set; } public string Bio { get; set; } public bool RememberMe { get; set; } } private FormModel model new FormModel(); private string message; private DraftMonitorFormModel draftMonitor; private DraftOptions draftOptions new DraftOptions { Key user-registration-form, DelayMilliseconds 1000, RecoveryMode DraftRecoveryMode.Confirm, Version 1.0.0 }; private void OnModelChanged(FormModel newModel) { model newModel; StateHasChanged(); } private void OnFinish(EditContext editContext) { // 提交成功后清除草稿防止下次访问时误恢复 _ draftMonitor?.ClearDraftAsync(); } private void OnDraftRecovered(FormModel recovered) { message Draft recovered!; } private void OnDraftDeleted() { message Draft deleted!; } private async Task ClearDraft() { if (draftMonitor ! null) { await draftMonitor.ClearDraftAsync(); message Draft cleared!; } } private void Reset() { model new FormModel(); message Form reset!; }几个关键细节refdraftMonitor拿到组件引用用于在OnFinish提交成功后调用ClearDraftAsync()清理草稿DataChanged必须把新数据写回表单的绑定模型否则Form不会感知草稿恢复后的数据在表单模型上使用DataAnnotations验证特性如[Required]、[EmailAddress]、[MinLength]Form的OnFinishFailed会拦截未通过校验的提交草稿机制与表单校验完全解耦。DraftOptions 配置详解Key、延迟、恢复模式与版本DraftOptions是草稿功能的全部配置入口定义见 DraftOptions.cs。下表汇总了全部参数与官方 API 文档 index.zh-CN.md 一致参数说明类型默认值Key草稿唯一标识符用于区分不同表单/数据建议语义化命名string无组件自动生成draft-monitor-{TData.Name}DelayMilliseconds延迟保存时长毫秒防抖间隔int1000RecoveryMode恢复模式见下节DraftRecoveryModeConfirmVersion当前版本号参与版本校验string1.0.0EnableVersionCheck是否启用版本检查booltrueEnabled是否启用草稿功能可整体开关booltrueStorageProvider自定义存储提供者默认使用 LocalStorageIDraftStorageProvidernullShouldRecoverDraft自定义版本比较函数(draftVersion, currentVersion) boolFuncstring, string, boolnull延迟保存的防抖原理DraftService.SaveDraftAsync是防抖的核心实现见 DraftService.cs每次调用会先通过CancelPendingSave(key)取消上一次未触发的延迟任务再注册一个新的CancellationTokenSourceTask.Delay(options.DelayMilliseconds, cts.Token)到期后才真正写入存储。因此用户连续输入时只有停顿超过DelayMilliseconds才会落盘避免高频写localStorage。官方基础演示 Basic.razor 中将其调低为 500ms 以加快落盘节奏。三种恢复模式Confirm / Auto / Manual恢复模式由DraftRecoveryMode枚举控制定义见 DraftRecoveryMode.cs在 DraftMonitor.razor.cs 的InitializeDraft中被分发处理值行为适用场景Confirm弹出确认对话框由用户选择「恢复」或「删除」默认模式尊重用户选择适合大多数表单Auto页面加载后自动恢复草稿无需交互纯草稿场景、无数据安全顾虑的本地编辑Manual不自动恢复仅在检测到草稿时通过回调通知开发者自行处理需要自定义恢复时机与 UI 的场景Confirm模式内部通过注入的ModalService弹出确认框标题与按钮文案来自本地化配置DraftLocaleRecoveryTitle/RecoveryContent/RecoveryOkText/RecoveryCancelText。若配置了RecoveryContentTemplate自定义模板则会优先渲染模板作为对话框内容。版本控制只恢复与当前版本匹配的草稿当表单数据结构升级例如新增必填字段、改变校验规则后旧草稿恢复可能导致崩溃或数据不兼容。DraftMonitor内置版本控制保存草稿时DraftService会把options.Version一并写入DraftDataT见 DraftData.cs 的Version属性读取草稿时执行双重校验LoadDraftAsync内若EnableVersionCheck为 true 且版本不一致则直接返回nullDraftService.csDraftMonitor.InitializeDraft中若版本不匹配还会主动调用RemoveDraftAsync清理过期草稿DraftMonitor.razor.cs。默认采用字符串相等比较。如果希望更灵活如「草稿版本 当前版本才恢复」可配置ShouldRecoverDraft自定义比较函数。官方版本控制演示 VersionControl.razor 给出了一个典型实现private DraftOptions draftOptions new DraftOptions { Key version-control-demo, DelayMilliseconds 1000, RecoveryMode DraftRecoveryMode.Confirm, Version formData.Version.ToString(), EnableVersionCheck true, // 自定义版本比较仅当草稿版本 当前版本时恢复 ShouldRecoverDraft (draftVersion, currentVersion) { if (int.TryParse(draftVersion, out var draftVer) int.TryParse(currentVersion, out var currentVer)) { return draftVer currentVer; } return false; } };演示中的典型场景用户 A 离线编辑形成草稿此时用户 B 已在服务器上把文档版本更新到更高值用户 A 重新打开页面时旧草稿低版本会自动删除且不再弹出恢复框避免覆盖服务器上的新数据。本地化默认多语言与自定义文案恢复确认框的文案由DraftLocale类提供见 DraftLocale.csDraftMonitor的Locale参数默认取LocaleProvider.CurrentLocale.Draft随应用全局语言环境自动切换。仓库内置语言包中 zh-CN.json 与 en-US.json 均已提供对应文案字段zh-CNen-USRecoveryTitle发现草稿Draft FoundRecoveryContent检测到未完成的草稿是否恢复\n\n保存时间${time}An unfinished draft was detected. Would you like to recover it?\n\nSaved at: ${time}RecoveryOkText恢复RecoverRecoveryCancelText删除Delete其中${time}占位符会被替换为草稿的实际保存时间draft.SavedAt.ToLocalTime().ToString(yyyy-MM-dd HH:mm:ss)见 DraftMonitor.razor.cs。如需自定义文案直接传入Locale参数即可官方演示见 Localization.razorprivate DraftLocale _customLocale new DraftLocale { RecoveryTitle Found a Draft!, RecoveryContent We detected an unfinished draft saved at {time}. Would you like to restore it?, RecoveryOkText Yes, Restore, RecoveryCancelText No, Delete };自定义恢复对话框RecoveryContentTemplate默认确认框只有一行提示文本。若希望展示草稿摘要保存时间、版本、已填写的字段等可使用RecoveryContentTemplate传入RenderFragmentDraftDataTData自定义内容。官方演示 CustomTemplate.razor 展示了用Descriptions组件渲染草稿明细的做法DraftMonitor TDataFormModel Data_model DataChanged((v) _model v) Options(new DraftOptions { Key demo-custom-template }) RecoveryContentTemplateRecoveryTemplate / code { private RenderFragmentDraftDataFormModel RecoveryTemplate draft div Alert TypeAlertType.Info MessageUnfinished draft detected DescriptionGetDraftSummary(draft) ShowIcontrue / Divider / Descriptions TitleDraft Details Bordered SizeDescriptionsSize.Small DescriptionsItem TitleSaved Timedraft.SavedAt.ToLocalTime().ToString(yyyy-MM-dd HH:mm:ss)/DescriptionsItem DescriptionsItem TitleVersiondraft.Version/DescriptionsItem DescriptionsItem TitleUsernamedraft.Data.Username/DescriptionsItem DescriptionsItem TitleEmaildraft.Data.Email/DescriptionsItem DescriptionsItem TitleRemarks Span3draft.Data.Remarks/DescriptionsItem /Descriptions /div; }模板参数DraftDataFormModel暴露了Data草稿数据、Version版本号、SavedAt保存时间与Key草稿键四个属性可在恢复前向用户完整呈现草稿上下文。存储层与底层实现从 LocalStorage 到自定义 Provider服务注册使用DraftMonitor前需确保调用AddAntDesign()完成服务注册其中IDraftService → DraftService以 Scoped 生命周期注册ServiceCollectionExtensions.cs。默认 LocalStorage 存储默认存储提供者是LocalStorageDraftProviderLocalStorageDraftProvider.cs它通过IJSRuntime直接调用浏览器localStorage的setItem/getItem/removeItem并给存储键统一加上ant-design-blazor-draft-前缀例如Key user-registration-form实际存储键为ant-design-blazor-draft-user-registration-form。存放到localStorage的内容是DraftDataT的 JSON 序列化结果包含Data、Version、SavedAt、Key四个字段。自定义存储提供者对于需要跨设备同步、数据量大或需加密的场景可实现IDraftStorageProvider接口IDraftStorageProvider.cs接入数据库、服务端 API 或其他存储public class DatabaseDraftProvider : IDraftStorageProvider { private readonly MyDbContext _db; public async Task SaveAsync(string key, string data) { // 保存到数据库 } public async Taskstring LoadAsync(string key) { // 从数据库加载 } public async Task RemoveAsync(string key) { // 从数据库删除 } public async Taskbool ExistsAsync(string key) { // 检查是否存在 } }自定义提供者有两种接入方式全局替换注册为IDraftStorageProvider服务后所有未显式指定StorageProvider的草稿都会使用它参考 index.zh-CN.mdbuilder.Services.AddAntDesign(); builder.Services.AddScopedIDraftStorageProvider, DatabaseDraftProvider();单表单指定在DraftOptions.StorageProvider上直接赋值实现不同表单使用不同存储。直接使用 IDraftService若不想依赖DraftMonitor组件例如在业务服务中保存草稿可直接注入IDraftServiceIDraftService.csinject IDraftService DraftService code { private async Task SaveDraft() { await DraftService.SaveDraftAsync(key, data, options); } private async Task LoadDraft() { var draft await DraftService.LoadDraftAsyncMyData(key, options); } }该接口提供五个方法SaveDraftAsync延迟保存、SaveDraftImmediateAsync立即保存、LoadDraftAsync读取版本不匹配返回 null、RemoveDraftAsync删除、HasDraftAsync检测是否存在且版本匹配、CancelPendingSave取消挂起的延迟保存。组件生命周期源码剖析从源码 DraftMonitor.razor.cs 可梳理出DraftMonitorTData的关键行为首次渲染OnAfterRenderAsync且Enabled且未初始化调用InitializeDraft()——先HasDraftAsync检测存在则LoadDraftAsync读取按EnableVersionCheck与ShouldRecoverDraft判定是否可恢复再根据RecoveryMode走 Auto 恢复、Confirm 弹框或 Manual 忽略分支参数变更OnParametersSetAsync将Data序列化后与_currentDataJson比较发生变化则更新快照并触发SaveDraft()内部为延迟保存恢复动作RecoverDraft优先调用OnUpdate回调否则调用DataChanged随后触发OnRecovered并将恢复后的数据作为新的基线快照公共方法SaveDraftAsync()手动立即保存、ClearDraftAsync()手动清除草稿二者在演示中都通过ref引用被调用。注意事项与最佳实践官方文档 index.zh-CN.md 明确给出了以下使用建议务必遵守版本控制建议为每个草稿设置版本号当数据结构变更时更新Version避免恢复不兼容的旧草稿存储限制localStorage通常只有 5-10MB 的存储上限大型数据请改用自定义存储提供者敏感数据不要在草稿中存储密码等敏感信息确有必要时应使用加密的自定义存储提供者表单中的密码字段建议留空参与草稿或对字段做脱敏处理定期清理草稿数据长期占用本地存储建议在成功提交后统一调用ClearDraftAsync()并定期清理过期 Key多标签页当前实现基于localStorage同一浏览器多个标签页共享同一份草稿如需隔离请使用包含标签页标识的Key。此外还需注意DraftMonitor属于Experimental分类见 Draft 文档目录API 可能在后续版本中调整接入生产环境前建议锁定组件库版本并跟进其变更日志。小结DraftMonitorForm的组合以极低的侵入成本为任意表单补齐了「自动保存 断点续填」的完整能力闭环Data/DataChanged建立数据关联DraftOptions控制延迟、恢复模式与版本IDraftService与IDraftStorageProvider提供了从浏览器本地存储到任意后端的存储抽象。核心源码均可在 components/draft 目录下查阅官方演示与 API 文档位于 Draft 演示目录。按照本文的步骤接入并配置版本号你的表单即可在用户意外离开后安全地找回现场。赞分享前端UI组件设计系统【免费下载链接】ant-design-blazor基于 Ant Design 与 Blazor 的前端组件库。让开发者解放生产力实现更大价值。项目地址https://gitcode.com/ant-design-blazor/ant-design-blazor点击查看免费下载相关推荐ant-design-blazor DraftMonitor 组件实战任意数据类型的草稿自动保存与恢复ant design blazor DraftMonitor 组件实战任意数据类型的草稿自动保存与恢复 在 Blazor 应用中用户填写长表单或编辑复杂配置前端UI组件设计系统ant-design-blazor Draft 草稿组件进阶用 RecoveryContentTemplate 自定义恢复确认对话框内容ant design blazor Draft 草稿组件进阶用 RecoveryContentTemplate 自定义恢复确认对话框内容 Draft草稿自动前端UI组件设计系统drawio-desktop草稿管理自动保存与恢复的实现drawio desktop草稿管理自动保存与恢复的实现 你是否曾经在绘制复杂图表时突然断电或程序崩溃导致数小时的工作付诸东流drawio desktop桌面应用图形学上一篇PEX锁文件深度解析确保Python项目依赖的完全确定性下一篇终极PowerShell混淆防御指南从命令混淆到检测策略的完整解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考