ReactiveFromNow.vue 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. <script setup lang="ts">
  2. import dayjs from 'dayjs'
  3. import relativeTime from 'dayjs/plugin/relativeTime'
  4. const props = defineProps<{
  5. time?: string | number
  6. }>()
  7. dayjs.extend(relativeTime)
  8. const text = ref('')
  9. const time = computed(() => {
  10. if (!props.time)
  11. return ''
  12. if (typeof props.time === 'number')
  13. return props.time
  14. return Number.parseInt(props.time)
  15. })
  16. let timer: NodeJS.Timeout
  17. let step: number = 1
  18. async function computedText() {
  19. if (!time.value)
  20. return
  21. // if time is not today, return the datetime
  22. const thatDay = dayjs.unix(time.value).format('YYYY-MM-DD')
  23. if (dayjs().format('YYYY-MM-DD') !== dayjs.unix(time.value).format('YYYY-MM-DD')) {
  24. clearInterval(timer)
  25. text.value = thatDay
  26. return
  27. }
  28. text.value = dayjs.unix(time.value).fromNow()
  29. clearInterval(timer)
  30. timer = setInterval(computedText, step * 60 * 1000)
  31. step += 5
  32. if (step >= 60)
  33. step = 60
  34. }
  35. onMounted(computedText)
  36. watch(() => props.time, computedText)
  37. </script>
  38. <template>
  39. <div class="reactive-time inline">
  40. {{ text }}
  41. </div>
  42. </template>
  43. <style scoped lang="less">
  44. </style>