当前位置: 首页 > news >正文

uniapp 防止长表单数据丢失方案,缓存表单填写内容,放置卡退或误操作返回。

防止长表单数据丢失方案,缓存表单填写内容,放置卡退或误操作返回。

一、存储方案(多端兼容)

1. 使用 UniApp 的数据存储 API

// utils/storage.js
export class FormDraftManager {constructor(formKey = 'formDraft') {this.formKey = formKey;}// 保存草稿saveDraft(formData) {const draft = {data: formData,timestamp: Date.now(),formVersion: '1.0'};try {uni.setStorageSync(this.formKey, draft);return true;} catch (e) {console.error('保存草稿失败:', e);return false;}}// 获取草稿getDraft() {try {return uni.getStorageSync(this.formKey);} catch (e) {console.error('读取草稿失败:', e);return null;}}// 清除草稿clearDraft() {try {uni.removeStorageSync(this.formKey);return true;} catch (e) {console.error('清除草稿失败:', e);return false;}}// 检查草稿是否有效(例如24小时内)isDraftValid(draft, maxAge = 24 * 60 * 60 * 1000) {if (!draft || !draft.timestamp) return false;return (Date.now() - draft.timestamp) < maxAge;}
}

二、恢复确认弹窗实现

1. 使用 UniApp 的模态框 API

// pages/your-form-page.vue
<script>
import { FormDraftManager } from '@/utils/storage.js';export default {data() {return {formData: {name: '',email: '',phone: '',// ...其他表单字段},draftManager: new FormDraftManager(),hasRecovered: false}},onLoad() {this.checkAndRecoverDraft();},onUnload() {// 页面卸载时自动保存(可选)this.autoSaveDraft();},methods: {// 检查并恢复草稿async checkAndRecoverDraft() {const draft = this.draftManager.getDraft();if (this.draftManager.isDraftValid(draft)) {// 显示恢复确认弹窗this.showRecoveryConfirm(draft);}},// 显示恢复确认弹窗showRecoveryConfirm(draft) {const formattedTime = this.formatTime(draft.timestamp);uni.showModal({title: '恢复填写进度?',content: `检测到您上次在 ${formattedTime} 有未提交的表单内容,是否恢复?`,confirmText: '恢复数据',cancelText: '重新开始',confirmColor: '#007AFF',success: (res) => {if (res.confirm) {this.restoreFormData(draft.data);} else {this.clearDraft();}}});},// 恢复表单数据restoreFormData(draftData) {this.formData = { ...this.formData, ...draftData };this.hasRecovered = true;// 显示成功提示uni.showToast({title: '数据恢复成功',icon: 'success',duration: 2000});},// 自动保存草稿autoSaveDraft() {// 检查表单是否有内容if (this.hasFormData()) {this.draftManager.saveDraft(this.formData);}},// 检查表单是否有数据hasFormData() {return Object.values(this.formData).some(value => value !== '' && value !== null && value !== undefined);},// 清除草稿clearDraft() {this.draftManager.clearDraft();},// 格式化时间formatTime(timestamp) {const date = new Date(timestamp);return `${date.getMonth() + 1}月${date.getDate()}日 ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;},// 表单提交async submitForm() {try {// 你的提交逻辑// await submitApi(this.formData);// 提交成功后清除草稿this.clearDraft();uni.showToast({title: '提交成功',icon: 'success'});} catch (error) {uni.showToast({title: '提交失败',icon: 'error'});}},// 手动保存草稿(可提供给用户操作)manualSaveDraft() {if (this.draftManager.saveDraft(this.formData)) {uni.showToast({title: '草稿已保存',icon: 'success'});}}}
}
</script>

三、实时自动保存(增强体验)

1. 防抖自动保存

// 在 data 中添加
data() {return {// ...其他数据autoSaveTimer: null}
},// 在 methods 中添加
methods: {// 输入时触发自动保存(防抖)onInput(field, value) {this.formData[field] = value;this.debouncedAutoSave();},// 防抖自动保存debouncedAutoSave() {if (this.autoSaveTimer) {clearTimeout(this.autoSaveTimer);}this.autoSaveTimer = setTimeout(() => {this.autoSaveDraft();}, 2000); // 2秒后自动保存},// 显示保存状态showSaveStatus() {// 可以在模板中显示保存状态this.saveStatus = '保存中...';setTimeout(() => {this.saveStatus = '已保存';setTimeout(() => {this.saveStatus = '';}, 2000);}, 500);}
}

四、模板部分

<template><view class="form-container"><!-- 保存状态提示 --><view v-if="saveStatus" class="save-status">{{ saveStatus }}</view><form @submit="submitForm"><view class="form-item"><text class="label">姓名</text><input class="input" v-model="formData.name" @input="onInput('name', $event.detail.value)"placeholder="请输入姓名" /></view><view class="form-item"><text class="label">邮箱</text><input class="input" v-model="formData.email" @input="onInput('email', $event.detail.value)"placeholder="请输入邮箱" type="email"/></view><view class="form-item"><text class="label">电话</text><input class="input" v-model="formData.phone" @input="onInput('phone', $event.detail.value)"placeholder="请输入电话" type="number"/></view><!-- 更多表单项... --><view class="form-actions"><button class="btn-save-draft" @click="manualSaveDraft" type="button">保存草稿</button><button class="btn-submit" form-type="submit">提交表单</button></view></form></view>
</template><style scoped>
.form-container {padding: 30rpx;
}.save-status {text-align: center;color: #07c160;font-size: 24rpx;margin-bottom: 20rpx;
}.form-item {margin-bottom: 40rpx;
}.label {display: block;margin-bottom: 10rpx;font-weight: bold;
}.input {border: 1px solid #ddd;border-radius: 8rpx;padding: 20rpx;font-size: 28rpx;
}.form-actions {display: flex;gap: 20rpx;margin-top: 60rpx;
}.btn-save-draft {flex: 1;background: #f8f9fa;color: #333;
}.btn-submit {flex: 2;background: #007AFF;color: white;
}
</style>

http://www.dtcms.com/a/461799.html

相关文章:

  • uniapp | 图片上传的两种实现方式(传统VS组件)
  • Android NDK 命令规范
  • C语言 分支结构(2)
  • 哪个做app的网站好排版设计技巧
  • 如何鉴赏网站论文wordpress静态nginx规则
  • 数据库存储中的哈希表和B+树
  • 绵阳网站推广优化和田知名网站建设企业
  • MQTT 协议应用指导
  • 蘑菇采摘公司:Mycionics
  • billfish本地资源库占内存吗
  • 深度残差网络(ResNet)
  • 专题五:位运算~
  • C++语言编程规范-资源分配和释放
  • 影视广告网站重庆网站建设制作
  • Hadess入门到实战(9) - 如何管理Composer(PHP)制品
  • 如何设计公司官网站苏宁易购网站风格
  • wx小程序扫码入口方式
  • Agent 开发设计模式(Agentic Design Patterns )第 1 章:提示词链
  • asp美食网站源码天津网站推广
  • 图像处理踩坑:浮点数误差导致的缩放尺寸异常与解决办法
  • Android Studio Meerkat 打开flutter项目没有自动选中main.dart configuration
  • OpenTiny TinyEngine 基础知识
  • 大模型-旋转位置编码(Rotary Positional Embedding)
  • 如何减小ES和mysql的同步时间差
  • this.$router.push 与 this.$router.replace 跳转的区别
  • 网站域名到期时间查询网站建设蛋蛋28
  • 建设网站选题应遵循的规则网站网页打开的速度什么决定的
  • 【Servlet】使用idea2023创建Servlet JavaWeb
  • 异步串口通信和逻辑分析仪
  • 中微电力建设公司网站建设人行官方网站