Markus Oberlehner

Vue Composition API: VueUse Composable Library


The Composition API makes it very easy to share code between components in our codebase or even across projects via npm packages. I recently stumbled upon the excellent VueUse library that provides us with a ton of valuable composables. In this article, we take a closer look at some of the most interesting ones.

Installing VueUse in Our Project

There are two ways how we can use VueUse in our projects. First, probably the most common way is to install it as a dependency:

npm install @vueuse/core

But in some cases, it can also make sense to copy & paste certain composables from the GitHub repository. E.g., if we only need a few specific composables and want to minimize our project’s dependency count. Or if we’re going to make some modifications to the way a particular composable works. Either way, I highly recommend you check out the code of the VueUse composables. There is a lot to learn in there about how to work with the Composition API.

Let’s take a look at three very useful composables in VueUse.

onClickOutside()

Imagine we’re building a dropdown menu or a modal popup. In such cases, what we need is a way to detect a click outside of our component. In situations like that, the onClickOutside() composable comes in handy.

<template>
  <div ref="root" class="BaseDropdown">
    <slot />
  </div>
</template>

<script>
import { ref } from "vue";
import { onClickOutside } from "@vueuse/core";

export default {
  setup(props, { emit }) {
    const root = ref(null);

    onClickOutside(root, () => emit("close"));

    return { root };
  },
};
</script>

useMediaQuery()

Another classic use case is that, for some reason, we need to know the current viewport size to adapt our UI accordingly. Here we can use the useMediaQuery() composable to determine if the viewport matches a specific media query, for example.

<template>
  <div>
    <!-- ... -->
    <FaqAccordion :is-open="isLargeScreen" />
  </div>
</template>

<script>
import { useMediaQuery } from "@vueuse/core";

export default {
  setup() {
    const isLargeScreen = useMediaQuery("(min-width: 1024px)");

    return { isLargeScreen };
  },
};
</script>

useIntersectionObserver()

One of my personal favorite new browser APIs of recent years is IntersectionObserver. It enables us to detect if an element is currently visible within the viewport or not. With the useIntersectionObserver() composable, we get a reactive API to do the same.

<template>
  <div ref="root">
    <!-- ... -->
  </div>
</template>

<script>
import { ref, watch } from "vue";
import { useIntersectionObserver } from "@vueuse/core";

import { startPolling, stopPolling } from "../composables/notifications";

export default {
  setup() {
    const root = ref(null);
    const isVisible = ref(false);

    useIntersectionObserver(root, ([{ isIntersecting }]) => {
      isVisible.value = isIntersecting;
    });

    watch(isVisible, () => {
      if (isVisible.value) {
        startPolling();
      } else {
        stopPolling();
      }
    });

    return { root };
  },
};
</script>

Wrapping It Up

Those were only a couple of the most helpful composables we can import from the fantastic VueUse package. I highly recommend you to check out the VueUse documentation page with all the other composables ready for you to explore and use in your projects.