Skip to content

Instantly share code, notes, and snippets.

@toniengelhardt
Last active January 25, 2022 00:04
Show Gist options
  • Save toniengelhardt/eb1026216bd148395aed64ea2d945f2b to your computer and use it in GitHub Desktop.
Save toniengelhardt/eb1026216bd148395aed64ea2d945f2b to your computer and use it in GitHub Desktop.
Simple Vue 3 TimeAgo component
<template>
<span class="timeago">{{ timeago }}</span>
</template>
<script setup lang="ts">
interface Props {
datetime: Date
refreshInterval?: number
timeFormat?: string
dateFormat?: any
}
const props = withDefaults(defineProps<Props>(), {
datetime: () => new Date(),
refreshInterval: 10,
timeFormat: 'long', // or short
dateFormat: {
year: 'numeric',
month: 'short',
day: 'numeric',
}
})
const emit = defineEmits<{
(event: 'update'): void
}>()
const units: {
[key: string]: {
[key: string]: string
}
} = {
'short': {
year: 'y',
month: 'M',
day: 'd',
hour: 'h',
minute: 'm',
second: 's',
},
'long': {
year: ' year',
month: ' month',
day: ' day',
hour: ' hour',
minute: ' minute',
second: ' second',
},
}
let timer: any = null
const timeago = ref('')
function updateTime(): void {
const now = new Date()
let elapsedTime = (now.getTime() - props.datetime.getTime()) / 1000
if (elapsedTime <= 0 || Math.floor(elapsedTime / 60) <= 0) {
timeago.value = 'now'
} else if (elapsedTime < 3600) {
const mins = Math.round(elapsedTime / 60)
timeago.value = `${mins}${units[props.timeFormat].minute}${mins !== 1 ? 's' : ''} ago`
} else if (elapsedTime >= 3600 && Math.round(elapsedTime / 3600) < 24) {
const hours = Math.round(elapsedTime / 3600)
timeago.value = `${hours}${units[props.timeFormat].hour}${hours !== 1 ? 's' : ''} ago`
} else if (elapsedTime / 86400 <= 31) {
const days = Math.round(elapsedTime / 86400)
timeago.value = `${days}${units[props.timeFormat].day}${days !== 1 ? 's' : ''} ago`
} else {
timeago.value = new Intl.DateTimeFormat('en', props.dateFormat).format(props.datetime)
}
if (elapsedTime) {
emit('update')
}
}
function createTimer(): void {
updateTime()
timer = setInterval(updateTime, props.refreshInterval * 1000)
}
function clearTimer(): void {
if (timer) clearInterval(timer)
}
onMounted(() => { createTimer() })
onUnmounted(() => { clearTimer() })
watch(() => props.datetime, () => updateTime())
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment