Skip to main content

Command Palette

Search for a command to run...

Creating Smooth Animated Counters in Vue 3 with Composables

Updated
โ€ข4 min read
Creating Smooth Animated Counters in Vue 3 with Composables
N

Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet

In modern web applications, animated counters can significantly enhance user experience by providing visual feedback and making data changes more engaging. In this blog post, we'll explore how to create a reusable animated counter in Vue 3 using composables. We'll build a flexible solution that can animate any numeric property in your Vue store, with customizable duration.

Understanding the Problem

Often, when displaying numerical data that changes frequently, such as search result counts or user statistics, abrupt updates can be jarring to users. A smooth animation between the old and new values can make these changes more pleasant and noticeable.

The Solution: A Custom Composable

Understanding Composables in Vue 3
Composables are a fundamental feature of Vue 3's Composition API. They provide a way to encapsulate and reuse stateful logic across multiple components. Here's a more detailed look at composables:

Key Characteristics of Composables

  • They're Just Functions: Composables are plain JavaScript functions, making them easy to understand and test.

  • They Can Use Composition API Features: Composables can use reactive state, computed properties, watchers, and lifecycle hooks.

  • They Return an Object: Typically, composables return an object containing reactive state and methods.

  • They're Flexible: Composables can accept parameters, allowing for customization.

We'll create a composable function called useAnimatedCount that takes care of the animation logic. This composable will:

  1. Accept a store object, a path to the property we want to animate, and an animation duration.

  2. Return a reactive value that smoothly animates from the current value to the new value whenever the source data changes.

Let's break down the implementation:

useAnimatedCount.js

import { isRef, ref, watch } from "vue"

function getNestedValue(obj, path) {
    const keys = path.split(".")
    let value = obj
    for (const key of keys) {
        if (value && typeof value === "object" && key in value) {
            value = value[key]
        } else {
            return undefined
        }
    }
    return value
}

function setNestedValue(obj, path, value) {
    const keys = path.split(".")
    let target = obj
    for (let i = 0; i < keys.length - 1; i++) {
        const key = keys[i]
        if (!target[key]) target[key] = {}
        target = target[key]
    }
    target[keys[keys.length - 1]] = value
}

export function useAnimatedCount(store, storePropertyPath, duration) {
    const animatedValue = ref(0)
    const durationRef = isRef(duration) ? duration : ref(duration || 500)

    const animateValue = () => {
        const startValue = animatedValue.value
        const endValue = getNestedValue(store, storePropertyPath)
        const startTime = performance.now()

        const step = (currentTime) => {
            const elapsedTime = currentTime - startTime
            const progress = Math.min(elapsedTime / durationRef.value, 1)
            const newValue = Math.floor(startValue + (endValue - startValue) * progress)
            setNestedValue(animatedValue, "value", newValue)

            if (elapsedTime < durationRef.value) {
                requestAnimationFrame(step)
            }
        }

        requestAnimationFrame(step)
    }

    watch(
        () => getNestedValue(store, storePropertyPath),
        () => {
            animateValue()
        }
    )

    watch(durationRef, () => {
        animateValue()
    })

    return animatedValue
}

Key Components of the Solution

  1. Helper Functions: getNestedValue and setNestedValue allow us to work with nested object properties using dot notation.

  2. Reactive References: We use ref to create reactive values for the animated count and duration.

  3. Animation Logic: The animateValue function uses requestAnimationFrame to create a smooth animation between the current and target values.

  4. Watchers: We set up watchers to trigger the animation when either the source data or the duration changes.

Using the Composable

Here's how you can use the useAnimatedCount composable in your Vue component:

<script setup>
import { useAnimatedCount } from './useAnimatedCount'
import { store } from './store'

const searchCount = useAnimatedCount(store, "searchCount", ref(1500))
</script>

<template>
  <div>
    {{ jobSearchCount }}
  </div>
</template>

In this example, we're animating the searchCount property from our store, with an animation duration of 1500 milliseconds.

Benefits of This Approach

  1. Reusability: The composable can be used with any numeric property in your store.

  2. Flexibility: The animation duration can be easily customized and even changed dynamically.

  3. Smooth Updates: Users see a smooth transition between old and new values, improving the overall user experience.

  4. Performance: By using requestAnimationFrame, we ensure that the animation is optimized for browser performance.

Conclusion

Animated counters are a small but impactful way to improve the user experience of your Vue application. By leveraging Vue 3's composition API and creating a custom composable, we've built a reusable solution that can be easily integrated into any component.

This technique not only enhances the visual appeal of your application but also demonstrates the power and flexibility of Vue 3's composition API for creating reusable logic.

Remember, while animations can greatly improve user experience, they should be used judiciously. Always consider the context and ensure that animations enhance rather than distract from the user's primary tasks.

๐Ÿ‘๐Ÿ‘ By coming this far I hope you can implement this awesome counter animated effect on your project. So, I suggest you give it a try on your project and enjoy it!

Feel free to share your thoughts and opinions and leave me a comment if you have any problems or questions.

Till then, Keep on Hacking, Cheers

J

In March 2024, I found myself facing a bad scenario that many in the cryptocurrency space dread โ€“ falling victim to a phishing scam and losing a substantial amount of Bitcoin, totaling around $300,000. It was a devastating blow, one that left me feeling helpless and betrayed by the very technology I had come to trust. However, amidst the despair, a glimmer of hope emerged in the form of Digital Hack Recovery. In the attack, I was determined to learn from my mistake and take proactive measures to prevent such incidents from happening again. I delved into the world of cryptocurrency security, absorbing every piece of information I could find to arm myself against future threats. It was during this research phase that I came across Digital Hack Recovery, a name that would soon become synonymous with salvation. What struck me initially about Digital Hack Recovery was their emphasis on education and awareness. They understood that ignorance was often the greatest vulnerability in the crypto space and sought to empower their clients with the knowledge to mitigate risks effectively. Their website was a treasure trove of resources, offering comprehensive guides on security best practices, common scams to watch out for, and steps to take in the event of a breach. It was evident that they were not just a recovery service but a beacon of guidance in a sea of uncertainty. Upon reaching out to Digital Hack Recovery, I was met with a level of expertise that immediately put me at ease. Unlike other recovery platforms I had encountered, they took the time to assess my case thoroughly before committing to any action. Their transparency was refreshing โ€“ they made it clear from the outset what the likelihood of success was and what steps would be involved in the recovery process. This level of honesty instilled confidence in their capabilities and gave me hope that all was not lost. Throughout the recovery journey, Digital Hack Recovery maintained clear and open communication, providing regular updates on their progress and patiently answering any questions or concerns I had along the way. Their dedication to customer satisfaction was evident in every interaction, and it was clear that they genuinely cared about restoring not just my funds but also my peace of mind. In the end, Digital Hack Recovery delivered on its promise, managing to recover approximately 80% of the funds I had lost to the scam. While the financial aspect was certainly significant, it was the sense of closure and justice that proved to be the most valuable takeaway. Thanks to their expertise and perseverance, I was able to reclaim a portion of what was rightfully mine and move forward with renewed confidence in the crypto landscape. I cannot recommend Digital Hack Recovery highly enough to anyone who finds themselves in a similar predicament. Their commitment to education, transparency, and customer satisfaction sets them apart as a beacon of hope in an otherwise tumultuous industry. While the scars of my ordeal may never fully heal, knowing that there are professionals like Digital Hack Recovery standing ready to assist brings a sense of comfort and reassurance that is truly priceless. Trusting them with my recovery was undoubtedly one of the best decisions I have ever made, and I am eternally grateful for their unwavering support. Their contact;

WhatsApp +19152151930

Email; digital hack recovery @ techie . com

More from this blog

JoBins Blog

163 posts