用 uni-app 实现本地留言板需用 uni.setStorageSync/uni.getStorageSync 持久化数据,关键在避免错乱:确保唯一 id、校验非空、onShow 刷新、正确清空输入框、v-for 用 item.id 作 key、时间格式兼容处理。

如何用 uni-app 实现本地留言板(无后端)
直接用 uni-app 做纯前端留言板,核心是靠 uni.setStorageSync 和 uni.getStorageSync 持久化数据。不连服务器也能存删查,适合原型验证或离线小工具。
关键点不是“能不能做”,而是“怎么避免数据错乱”:比如多页切换时没及时刷新列表、输入框没清空、时间戳用 Date.now() 而非 new Date().toLocaleString() 导致中文环境显示异常。
- 所有留言对象必须带唯一
id(建议用Date.now() + Math.random().toString(36).substr(2, 9)拼接,避免重复) - 提交前校验
content非空且去除首尾空格,否则会存入空白项 - 删除操作别直接用
splice改原数组,应生成新数组再setData,否则 Vue 响应式可能失效 - 页面
onShow钩子中重新读取存储数据,确保从其他页返回时列表最新
uni-app 中 v-model 绑定与表单重置的坑
很多人写完提交逻辑就忘了清空输入框,或者用 v-model 绑定一个变量后,在 submit 后直接赋值为空字符串,结果下次聚焦输入框时光标跳到开头——这是 Vue 2 的响应式更新机制导致的。
正确做法是:提交成功后,先重置 data 中的绑定变量,再调用 uni.hideKeyboard() 防止软键盘残留。
立即学习“前端免费学习笔记(深入)”;
- 不要写
this.content = ''后立刻uni.showToast,要等下一次 tick:this.$nextTick(() => uni.hideKeyboard()) - 如果用了自定义组件封装输入框,确保其内部用
props接收值、$emit('input')向上同步,否则v-model失效 - 在 H5 端测试时,注意
uni.hideKeyboard()对部分浏览器无效,可加document.activeElement?.blur()兜底
列表渲染性能问题:为什么滚动卡顿、删除闪一下
留言一多(比如超 50 条),用 v-for="item in list" 直接渲染,配合默认过渡动画,很容易在小程序端出现卡顿或删除时整个列表重绘——根本原因是没给 v-for 加 key,或 key 用了不稳定值(如索引 :key="index")。
- 必须用每条数据的唯一
id作 key::key="item.id",不能用index - 避免在
render中计算时间格式,提前在存储时存好formattedTime字段,或用计算属性缓存 - 小程序平台慎用
<transition-group></transition-group>,真要加动画,用 CSStransform+opacity,别触发布局重排 - 超过 100 条建议加懒加载,但简单留言板通常不需要;更实际的是限制单次最多显示 20 条,加「加载更多」按钮
跨平台兼容性:iOS 微信小程序里日期显示为空?
new Date().toLocaleString() 在 iOS 微信小程序基础库 2.25.0 以下版本会返回空字符串,这是已知 bug。别在 data 初始化时直接调用它生成时间字段。
稳妥方案是封装一个兼容函数:
function getNowTime() {
const d = new Date()
return d.getFullYear() + '-' +
String(d.getMonth() + 1).padStart(2, '0') + '-' +
String(d.getDate()).padStart(2, '0') + ' ' +
String(d.getHours()).padStart(2, '0') + ':' +
String(d.getMinutes()).padStart(2, '0')
}
- 不要依赖
toLocaleString或toISOString渲染展示时间 - H5 端可放心用
toLocaleString,但小程序端必须降级处理 - 如果后续要对接后端,时间字段统一用毫秒时间戳(
Date.now())存储,展示层再格式化,避免时区混乱
真正难的不是写功能,是记住哪些 API 在哪个平台哪版基础库里会悄悄失效。留个心眼,比事后 debug 强得多。


















