如何在 Vue 3 项目中显示使用 date-fns 格式化的 Firestore 时间戳字段?

2023-12-29

在 Cloud Firestore 文档中标题为的集合中reviews,我有一个标题为的字段createdAt of timestamp type.

我正在尝试展示这一点createdAtDOM 中的字段使用date-fns https://date-fns.org/日期实用程序库格式距离现在 https://date-fns.org/v2.25.0/docs/formatDistanceToNow,它以单词形式返回给定日期和现在之间的距离,例如“不到一分钟” 前.

例如,在给定的 Firestore 文档中,createdAt is of timestamp键入值11/14/2021 10:49:09 上午

我能够访问并显示createdAt字段,如下:

<p>{{ review.createdAt }}</p>在 DOM 中的结果是:时间戳(秒=1636904949,纳秒=271000000)

<p>{{ review.createdAt.toDate() }}</p>在 DOM 中的结果是:2021 年 11 月 14 日星期日 10:49:09 GMT-0500(东部标准时间)

我试图显示 date-fns 格式的日期,如下所示:

In the <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 and review.createdAt.toDate()在 DOM 中显示得很好,<p> tags.

为什么是toDate()方法 (链接到 Firebase 文档中的内容 https://firebase.google.com/docs/reference/js/v8/firebase.firestore.Timestamp#todate)导致问题computedDateToNow?

UPDATE基于这条评论 https://stackoverflow.com/a/26002671/1459653“很可能这个 javascript 函数是在加载实际 html 之前放置的”我添加了一个if (review.createdAt)声明和错误消失,BUT 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>

谢谢你的帮助!


我可以建议的是使用npm 包 https://www.npmjs.com/package/vue-date-fns经理:

在这种情况下,您可以直接在组件中使用过滤器。

// my-component.js
import { dateFilter } from "vue-date-fns";
 
export default {
    filters: {
        date: dateFilter
    }
}

<!-- my-component.vue -->
<template>
    <div>Now: {{ new Date() | date }}</div>
</template>

如果您想继续使用当前代码,也许您可​​以尝试调试您的代码const computeDateToNow,看看您得到的值是什么。

根据您分享的文档date-fns https://date-fns.org/,这是 console.log 的示例:

console.log(format(new Date(), "'Today is a' eeee"))

输出应该是:

//=> "Today is a Wednesday"

这将帮助您验证该功能是否正常执行;如果没有,请验证库的导入。

一项建议可能是将数据类型从const 到 var。 请记住,var 可以更新和重新声明,而 const 不仅不能重新声明,而且不能重新赋值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Vue 3 项目中显示使用 date-fns 格式化的 Firestore 时间戳字段? 的相关文章

随机推荐