uni-app中推荐用dayjs替代Moment.js实现日期格式化,因其仅2KB、API兼容且支持按需引入;过滤器内须用require导入并显式extend插件,注意大小写敏感及空值防御;动态相对时间应使用computed而非filter。

uni-app里没有内置日期格式化,得自己封装或引入轻量库
uni-app默认不带类似 Moment.js 的日期处理能力,filter 语法也不支持直接调用第三方类库实例。硬塞 Moment.js 会增大包体积(约70KB+),且在小程序平台可能触发安全警告或兼容问题。实际项目中更推荐用原生 Date 封装 + 按需引入 dayjs(仅2KB)。
用 dayjs 替代 Moment.js 实现过滤器最稳妥
dayjs 是 Moment.js 的轻量替代,API 高度兼容,支持按需引入插件(如 relativeTime、locale),uni-app 各端(H5/小程序/App)均能正常运行。关键是要避免全局挂载污染,改用局部导入方式:
export default {
filters: {
formatDate(date, format = 'YYYY-MM-DD') {
if (!date) return ''
// 注意:不能 import dayjs from 'dayjs' 在 filters 内部 —— 会报错
const dayjs = require('dayjs')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat)
return dayjs(date).format(format)
}
}
}-
require而非import:避免编译时被 tree-shaking 或 H5 端模块解析失败 - 插件必须显式
extend:比如需要YYYY-MM-DD HH:mm解析就得加customParseFormat - 格式字符串用
YYYY(不是yyyy),MM(不是mm)——大小写敏感
v-model 绑定时间戳时,formatDate 过滤器容易传入 null/undefined
常见错误是后端返回 null 或空字符串,dayjs(null) 返回当前时间,导致显示异常。必须做防御性判断:
- 在过滤器开头加
if (!date || (typeof date === 'string' && !date.trim())) return '' - 若传入的是时间戳数字,但单位是秒(非毫秒),需先
date * 1000转换 - 小程序真机调试时,
new Date('2024-01-01')可能解析为Invalid Date,建议统一用dayjs(String(date))兜底
想支持「刚刚」「2小时前」这类相对时间?别用 filter,改用 computed 或方法
filters 是纯同步函数,无法响应式监听时间变化(比如每分钟更新「X分钟前」)。真正需要动态刷新的场景,必须用 computed 或 setInterval + data:
data() {
return {
now: Date.now()
}
},
computed: {
relativeTime() {
const dayjs = require('dayjs')
const relativeTime = require('dayjs/plugin/relativeTime')
dayjs.extend(relativeTime)
return dayjs(this.timestamp).fromNow()
}
},
mounted() {
this.timer = setInterval(() => {
this.now = Date.now()
}, 60000)
}注意:fromNow() 依赖当前时间,所以必须主动触发更新;且 clearInterval 别忘了在 beforeDestroy 里清理。
真正难的不是写格式化函数,而是判断该用 filter 还是 computed —— 静态展示选前者,实时刷新选后者。很多开发者卡在这一步,反复重载页面才看到更新,其实只是没意识到 filter 不响应时间变化。


















