【发布时间】:2021-12-26 23:12:12
【问题描述】:
在 Cloud Firestore 文档中,在标题为 reviews 的集合中,我有一个标题为 createdAt 的 timestamp 类型的字段。
我正在尝试使用 date-fns 日期实用程序库的 formatDistanceToNow 在 DOM 中显示该 createdAt 字段,它以单词形式返回给定日期与现在之间的距离,例如 " 小于一分钟前”。
例如,在给定的 Firestore 文档中,createdAt 是 timestamp 类型,其值为 11/14/2021 10:49:09 AM
我可以访问和显示createdAt 字段,如下所示:
<p>{{ review.createdAt }}</p> 在 DOM 中产生这样的结果:Timestamp(seconds=1636904949, nanoseconds=271000000)
<p>{{ review.createdAt.toDate() }}</p> 在 DOM 中产生以下结果:2021 年 11 月 14 日星期日 10:49:09 GMT-0500(东部标准时间)
我正在尝试按如下方式显示 date-fns 格式的日期:
在<template> 部分:<p>{{ computedDateToNow }}</p>
在<script> 部分:
const computedDateToNow = computed(() => {
return formatDistanceToNow(review.createdAt.toDate())
})
console.log(computedDateToNow)
我在控制台中遇到的错误是
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'toDate')
at ReactiveEffect.eval [as fn] (ReviewDetails.vue?5986:590)
at ReactiveEffect.run (reactivity.esm-bundler.js?a1e9:160)
at ComputedRefImpl.get value [as value] (reactivity.esm-bundler.js?a1e9:1087)
at unref (reactivity.esm-bundler.js?a1e9:1001)
at Object.get (reactivity.esm-bundler.js?a1e9:1004)
at Proxy.render (ReviewDetails.vue?5986:34)
at renderComponentRoot (runtime-core.esm-bundler.js?5c40:756)
at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js?5c40:4594)
at ReactiveEffect.run (reactivity.esm-bundler.js?a1e9:160)
at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:6987)
review.createdAt 和 review.createdAt.toDate() 在 DOM 中的 <p> 标签之间显示得很好。
为什么toDate() 方法(link to that in Firebase docs)会导致computedDateToNow 出现问题?
更新基于this comment,“很可能这个javascript函数是在实际html加载之前放置的”我添加了一个if (review.createdAt)语句并且错误消失了,但是 review.createdAt 在console.log(computedDateToNow) 中仍未定义
这是带有 if 语句的代码块:
const computedDateToNow = computed(() => {
if (review.createdAt) {
console.log('begin new console dot log',review.createdAt,'end new console dot log')
return formatDistanceToNow(review.createdAt.toDate())
}
})
添加(响应@Raffobaffo 的请求):
<script>
import useDocument from '@/composables/useDocument'
import getDocument from '@/composables/getDocument'
import { computed } from 'vue'
import { formatDistanceToNow } from 'date-fns'
export default {
props: ['id'],
components: { },
setup(props) {
const { error, document: review } = getDocument('reviews', props.id)
const { deleteDoc, updateDoc } = useDocument('reviews', props.id)
// BEGIN formatting timestamp
console.log('begin new console dot log',review.createdAt,'end new console dot log')
const computedDateToNow = computed(() => {
if (review.createdAt) {
console.log('begin new console dot log',review.createdAt,'end new console dot log')
return formatDistanceToNow(review.createdAt.toDate())
}
})
console.log(computedDateToNow)
// END formatting timestamp
return { error, review, formatDistanceToNow, computedDateToNow }
}
}
</script>
感谢您的帮助!
【问题讨论】:
-
console.log计算属性中的review.createdAt并检查它是否可用。在大多数情况下,我认为您的review.createAt日期当时不可用,可能是因为之后返回了来自firestore的响应。 -
谢谢@Salvino 您建议的console.log 回来了
undefined。我有些困惑,因为review.createdAt显示在 DOM 中。 -
不看你的代码很难理解这一点。请发布一个最小可重现问题,以便我们检查并为您提供合适的解决方案。
-
嗨,您可以将您定义
const computedDateToNow = computed(() => { return formatDistanceToNow(review.createdAt.toDate()) })的位置的完整部分粘贴到脚本中吗?是在setup函数里面吗? -
我刚刚添加了它。谢谢@Raffobaffo
标签: vue.js google-cloud-firestore vuejs3 date-fns