One solution is a counter that tracks the number of consumers of a particular style:
- When a component using this hook mounts:
- add the style to <head>
- increment the counter
 
- When that component unmounts:
- decrement the counter
- if the resulting count is zero, remove the style from <head>
 
Note this solution doesn't require tracking component instances, so there's no possibility of a memory leak here.
import { onBeforeMount, onUnmounted } from 'vue'
// map of injected CSS styles and their number of consumers
const injectedStyles = {} as Record<string, number>
function useGlobalStyles(cssStyles: string) {
    let styleEl: HTMLStyleElement
    onBeforeMount(() => {
        if (injectedStyles[cssStyles] === undefined) {
          injectedStyles[cssStyles] = 1
        } else {
          injectedStyles[cssStyles]++
          // style already injected, no need to do anything
          return
        }
        styleEl = document.createElement('style')
        styleEl.textContent = cssStyles
        document.head.appendChild(styleEl)
    })
    onUnmounted(() => {
        injectedStyles[cssStyles]--
        if (injectedStyles[cssStyles] <= 0) {
            delete injectedStyles[cssStyles]
            styleEl?.remove()
            styleEl = undefined
        }
    })
}
As a memory optimization, consider storing a hash of the styles in memory instead of the style strings themselves:
import { onBeforeMount, onUnmounted } from 'vue'
// https://stackoverflow.com/a/7616484/6277151
const hashCode = (str: string) => {
    let hash = 0
    if (str.length === 0) return hash
    for (let i = 0; i < str.length; i++) {
        let chr = str.charCodeAt(i)
        hash = ((hash << 5) - hash) + chr
        hash |= 0 // Convert to 32bit integer
    }
    return hash
}
// map of injected CSS style hashes and their number of consumers
const injectedStyles = {} as Record<string, number>
function useGlobalStyles(cssStyles: string) {
    let styleEl: HTMLStyleElement
    const styleHash = hashCode(cssStyles)
    onBeforeMount(() => {
        if (injectedStyles[styleHash] === undefined) {
          injectedStyles[styleHash] = 1
        } else {
          injectedStyles[styleHash]++
          // style already injected, no need to do anything
          return
        }
        styleEl = document.createElement('style')
        styleEl.textContent = cssStyles
        document.head.appendChild(styleEl)
    })
    onUnmounted(() => {
        injectedStyles[styleHash]--
        if (injectedStyles[styleHash] <= 0) {
            delete injectedStyles[styleHash]
            styleEl?.remove()
            styleEl = undefined
        }
    })
}