2

In the following example from the vue 3 documentation, we're creating a composable to track the mouse movement. https://vuejs.org/guide/reusability/composables.html#mouse-tracker-example

export function useMouse() {
    const x = ref(0)
    const y = ref(0)
    
    function update(event) {
        x.value = event.pageX
        y.value = event.pageY
    }
    
    onMounted(() => {
        console.log('mouse event listener bound')
        window.addEventListener('mousemove', update)
    })
    onUnmounted(() => {
        window.removeEventListener('mousemove', update)
    })

    return { x, y }
}

And then using it within our components to retreive the mouse position on the page.

<script setup>
import { useMouse } from './mouse.js'

const { x, y } = useMouse()
</script>

<template>Mouse position is at: {{ x }}, {{ y }}</template>

While this works, what I find strange is that using this method you end up with event listeners being attached for each component. So if there are 100 components using useMouse I'll have 100 event listeners attached to the body, each performing the update function which, when added up with other composables, can soon become a performance bottleneck.

Why is the official documentation recommending using this method? Wouldn't a singleton be better suited to this use case? If so how would I create a singleton composable, the vue3 documentation doesn't seem to mention singletons at all.

The Sloth
  • 367
  • 5
  • 18
  • They're just saying it works, should you need it. They're not recommending using it on 100 child components. Use it on the common parent of all children needing the mouse position and update the values in a store. And have the children read from store. (Or use child props, if you prefer prop drilling over using a store - I don't). – tao Jun 17 '22 at 03:17

1 Answers1

0

The document shows that example for the practical purpose only. So the way you are using the composable decides the impact of it on the performance.

If you want to use its function on 100 components at the same time, yes, a singleton would be a good option. But if you want to use the composable in many pages that are separated by the vue router, the composable is totally fine.

Duannx
  • 7,501
  • 1
  • 26
  • 59