Last active
January 25, 2022 00:04
-
-
Save toniengelhardt/eb1026216bd148395aed64ea2d945f2b to your computer and use it in GitHub Desktop.
Simple Vue 3 TimeAgo component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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