Last active
March 1, 2026 12:50
-
-
Save meduzen/6ee1cd0d8a3ce589862801e9ddfb4ce9 to your computer and use it in GitHub Desktop.
Approach for an updated current datetime (“now”) in a vue-x store (Vue 2/3) or a Pinia store (Vue 3)
This file contains hidden or 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
| const MILLISECONDS_PER_MINUTES = 1000 * 60; | |
| const state = { | |
| now: (new Date()), | |
| intervalTimer: null, | |
| }; | |
| const mutations = { | |
| now(state) { | |
| state.now = new Date(); | |
| }, | |
| setIntervalTimer(state, callback) { | |
| state.intervalTimer = setInterval(() => { | |
| if (callback) { | |
| callback(); | |
| } | |
| }, MILLISECONDS_PER_MINUTES * 3); | |
| }, | |
| clearIntervalTimer(state) { | |
| if (state.intervalTimer) { | |
| clearInterval(state.intervalTimer); | |
| state.intervalTimer = null | |
| } | |
| } | |
| }; | |
| const actions = { | |
| pollNow({ commit, state }) { | |
| if (!state.intervalTimer) { | |
| commit("setIntervalTimer", () => commit("now")); | |
| } | |
| }, | |
| clearPollNow({ commit }) { | |
| commit("clearIntervalTimer"); | |
| }, | |
| }; | |
| const time = { | |
| namespaced: true, | |
| state, | |
| mutations, | |
| actions, | |
| }; | |
| export default time; |
This file contains hidden or 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
| import { onBeforeMount, onUnmounted, ref } from 'vue' | |
| const REFRESH_INTERVAL_MS = 1000 | |
| let timer | |
| let subscribers = 0 | |
| /** Current date and time, updated every second. */ | |
| const now = ref(new Date()) | |
| const poll = () => { | |
| if (!timer) { | |
| timer = setInterval(() => { | |
| now.value = new Date() | |
| }, REFRESH_INTERVAL_MS) | |
| } | |
| } | |
| const stopPoll = () => { | |
| if (timer) { | |
| clearInterval(timer) | |
| timer = null | |
| } | |
| } | |
| /** | |
| * Subscribe to the polling of the current date and time. | |
| * Once subscribed, `now` is periodically updated. | |
| */ | |
| const subscribe = () => { | |
| if (!subscribers++) { | |
| poll() | |
| } | |
| } | |
| /** | |
| * Unsubscribe of the polling of the current date and time. | |
| * Once unsubscribed, `now` may stop to be updated. | |
| */ | |
| const unsubscribe = () => { | |
| subscribers-- | |
| if (!subscribers) { | |
| stopPoll() | |
| } | |
| } | |
| /** | |
| * Current date, updated every second. | |
| * | |
| * It start to update automatically on the first component to be mounted, and | |
| * stop updating on the last unmounted one. For non-component usages, use | |
| * `useNowSubscription`. | |
| */ | |
| export function useNow() { | |
| onBeforeMount(subscribe) | |
| onUnmounted(unsubscribe) | |
| return { now } | |
| } | |
| /** | |
| * Current date, updated every second. | |
| * | |
| * It requires manual (de)activation using (un)subscribe methods. Suitable in a | |
| * non-component environment (like a store). For components, use `useNow`. | |
| */ | |
| export const useNowSubscription = { subscribe, unsubscribe, now } |
Author
Author
Just added a useNow composable, suitable for Vue 3 composition API.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey, thanks for the feedback @cjbeattie! I forgot I made this gist. 😅