Vue+Firebase:如何将Firestore时间戳转为可读JavaScript日期
问题描述
我能从Firestore集合获取文档数据并转为数组渲染到视图,但不知道怎么把其中的时间戳值转成可读日期。现在视图里start、end字段显示成Timestamp(seconds=1663174800, nanoseconds=0),试了new Date(timeoffreq.start).toDateString()却得到Invalid Date,求正确转换方法。
获取数据代码
getDocs(collection(db, "timeoffreq")) .then((querySnapshot) => { const array = [] querySnapshot.forEach((doc) => { array.push(doc.data()) }); timeoffreq.value = array }) const timeoffreq = ref([{}])
视图渲染代码
<tr v-for="(timeoffreq, timeoffreqIdx) in timeoffreq" :key="timeoffreq.uid" :class="timeoffreqIdx % 2 === 0 ? 'bg-white' : 'bg-gray-50'"> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"> {{ timeoffreq.type }} </td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> {{ timeoffreq.desc }} </td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> {{ timeoffreq.start }} </td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> {{ timeoffreq.end }} </td> <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> <a href="#" class="text-indigo-600 hover:text-indigo-900">Edit</a> </td> </tr>
解决方法
Firestore返回的Timestamp是自定义对象,不是原生Date类型,不能直接传给new Date(),得用它自带的toDate()方法转换为原生Date对象后再格式化。以下是三种可行方案:
方案1:在数据获取阶段转换(推荐,统一处理)
拿到文档数据后,直接将Timestamp字段转为Date对象,后续视图可直接使用原生Date方法格式化:
getDocs(collection(db, "timeoffreq")) .then((querySnapshot) => { const array = [] querySnapshot.forEach((doc) => { const data = doc.data() // 将Timestamp转为原生Date对象 data.start = data.start?.toDate() data.end = data.end?.toDate() array.push(data) }); timeoffreq.value = array }) const timeoffreq = ref([{}])
视图中使用:
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> {{ timeoffreq.start.toDateString() }} </td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> {{ timeoffreq.end.toLocaleDateString('zh-CN') }} </td>
方案2:在视图中直接转换(无需修改数据源)
如果不想改动原始数据,可在Vue模板里直接调用toDate()后格式化:
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> {{ timeoffreq.start.toDate().toDateString() }} </td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> {{ timeoffreq.end.toDate().toLocaleString() }} </td>
方案3:封装工具函数(高复用性)
如果多处需要格式化日期,可封装工具函数统一处理:
// utils.js export function formatTimestamp(timestamp, type = 'date') { if (!timestamp) return '-' const date = timestamp.toDate() if (type === 'datetime') { return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }) } return date.toLocaleDateString('zh-CN') }
组件中导入使用:
<script setup> import { formatTimestamp } from './utils.js' // ...其他代码 </script> <template> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> {{ formatTimestamp(timeoffreq.start) }} </td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> {{ formatTimestamp(timeoffreq.end, 'datetime') }} </td> </template>
内容的提问来源于stack exchange,提问作者Avocado
相关产品推荐
相关产品推荐

