VueUse — это коллекция утилит для Vue Composition API, которая содержит средства для взаимодействия с различными сенсорами, API состояния, анимацией и другими возможностями браузеров. Помимо этого, также, включает в себя ряд интеграций со сторонними популярными пакетами.
Содержание
С помощью VueUse можно быстро реализовать следующие функции: копирование в буффер обмена, бесконечная прокрутка, локальные резервные копии данных на случай плохого соединения, работа с горячими клавишами, обработка статуса батареи, работа с фокусом на элементах, работа с вибрацией устройства и еще многое другое.
Коллекция очень разносторонняя. В этой статье делается попытка создать небольшой обзор ее возможностей. Конечно, каждую утилиту не описать в одной статье. Здесь содержатся упоминания тех, которые заинтересовали при чтении документации.
Группы функций VueUse
В документации функции VueUse разбиты на группы (категории).
- State. Реактивная работа с данными в доступных браузеру хранилищах LocalStorage/SessionStorage. Манипуляции с историей значений реактивных элементов (ref)
 - Elements. Взаимодействие с видимостью, размерами элементов, прокруткой, фокусом. Обработка перетаскивания и пересечения элементов.
 - Browser. Работа с функциями браузера. Буфер обмена, темы оформления страниц, контрольные точки размера экрана, права доступа (Permissions API), Web Workers, FileSystemAccessAPI, предпочитаемые языки, Web Share API, Vibration API, Screen Orientation API, BroadcastChannel API и другое.
 - Sensors. Использование Battery Status API, DeviceMotionEvent, DeviceOrientationEvent, Geolocation API, Network Information API, Pointer events, Web Speech API, TouchEvent, потоковых видео и звука, а также отслеживание выбранного текста и расширенная работа с клавиатурой и мышью.
 - Network. Работа с EventSource или Server-Sent-Events для открытия постоянного соединения с HTTP-сервером. Взаимодействие с WebSocket и Fetch API.
 - Animation. Использование Web Animations API и transitions для анимаций.
 - Component, Watch, Reactivity. Ряд универсальных утилит разработки компонентов, для развитой работы с реактивностью и отслеживанием состояний.
 - Array, Time. Работа в реактивном стиле с массивами и датами (временем).
 - Utilities. Другие утилиты, которые не вошли в другие разделы.
 
Add-ons
Также ряд вещей оформлен как дополнительные модули.
- Electron — поддержка одноименной библиотеки для создания межплатформенных приложений.
 - Firebase — работа с облачной платформой Firebase.
 - Head — реактивное управлений секцией head через UnHead
 - Integrations — интеграция с различными известными библиотеками. Например, axios, jwt-decode, qrcode, idb-keyval, async-validator, fuse (для нечеткого поиска), sortablejs и другими.
 - Math — набор математических функций.
 - Motion — предустановленный набор анимаций для элементов страницы с возможностью добавлять свои.
 - Router — улучшения для работы с vue-router (обработка параметров адресной строки, переданных различными способами).
 - RxJS — интеграция с одноименной библиотекой для создания асинхронных и событийно-ориентированных программ с использованием наблюдаемых последовательностей. Предоставляет один основной тип — Observable, вспомогательные типы (наблюдатель, планировщики, субъекты) и операторы, основанные на методах массива (map, filter, уменьшить, Every и т. д.), позволяющие обрабатывать асинхронные события как коллекции.
 - SchemaOrg — работа с метаданными страницы для поисковых систем по одноименному стандарту.
 - Sound — проигрывание звуковых файлов.
 
Некоторые возможности вблизи
Рассмотрим ряд утилит подробнее.
Создание хранилища через createGlobalState
Описать глобальное хранилище (наподобие Vuex) можно так:
// store.js
import { computed, ref } from 'vue'
import { createGlobalState } from '@vueuse/core'
export const useGlobalState = createGlobalState(
  () => {
    // state
    const count = ref(0)
    // getters
    const doubleCount = computed(() => count.value * 2)
    // actions
    function increment() {
      count.value++
    }
    return { count, doubleCount, increment }
  }
)
Когда мы сделали так, то в другом месте приложения можно вызвать объявленную здесь функцию useGlobalState и получить доступ к состоянию и функциях хранилища state = useGlobalState() . Это будет работать примерно также как и Vuex.
Создание хранилища в localStorage или sessionStorage
Данные состояния при перезагрузке страницы не сохраняются. Но мы могли бы сделать так, чтобы они хранились. Например, использовать localStorage или sessionStorage. Разница между этими методами хранения в том, что localStorage сохраняет данные при закрытии браузера, а sessionStorage неизбежно их теряет при этом.
Сделать глобальное хранилище на базе localStorage можно таким способом:
<script setup lang="ts">
import { stringify } from '@vueuse/docs-utils'
import { createGlobalState, useStorage } from '@vueuse/core'
const useState = createGlobalState(() =>
  useStorage('vue-use-locale-storage', {
    name: 'Banana',
    color: 'Yellow',
    size: 'Medium',
  }))
const state = useState()
const text = stringify(state)
</script>
<template>
  <div>
    <input v-model="state.name" type="text">
    <input v-model="state.color" type="text">
    <input v-model="state.size" type="text">
    <pre lang="yaml">{{ text }}</pre>
  </div>
</template>
Функция useStorage принимает первым параметром имя ключа, под которым данные будут храниться в localStorage, а вторым — начальное значение.
Если мы хотим использовать sessionStorage, то нужно использовать третий параметр useState:
// bind string with SessionStorage, returns Ref<string>
const id = useStorage('my-id', 'some-string-id', sessionStorage)
Асинхронное реактивное состояние через useAsyncState
Когда какие-либо данные мы получаем с сервера и соединение не очень быстрое, то в ряде случаев, неплохим решением будет отображение предыдущего сохраненного значения. Рассмотрим следующий пример для useAsyncState из документации:
<script setup lang="ts">
import axios from 'axios'
import YAML from 'js-yaml'
import { useAsyncState } from '@vueuse/core'
const { isLoading, state, isReady, execute } = useAsyncState(
  (args) => {
    const id = args?.id || 1
    return axios.get(`https://jsonplaceholder.typicode.com/todos/${id}`)
      .then(t => t.data)
  },
  {},
  {
    delay: 2000,
    resetOnExecute: false,
  },
)
</script>
<template>
  <div>
    <note>Ready: {{ isReady.toString() }}</note>
    <note>Loading: {{ isLoading.toString() }}</note>
    <pre lang="json" class="ml-2">{{ YAML.dump(state) }}</pre>
    <button @click="execute(2000, { id: 2 })">
      Execute
    </button>
  </div>
</template>
В useAsyncState первым аргументом передается промис, вторым — начальное значение, а третьим — опции. В данном случае используются опции delay (задержка в миллискундах перед выполнением прописа) и resetOnExecute (сброс или нет в начальное состояние перед выполнением промиса). В промисе описано получение данных с сервера.
Функция useAsyncState отдает ссылку на реактивную переменную с данными (state), индикаторы загрузки isLoading и isReady и функцию-действие execute(). Последняя функция позволяет выполнить промис снова с указанной задержкой (первый параметр) и новыми аргументами (второй параметр).
Итак, посмотрим как будет работать данный пример. Сначала будет работать указанная в опциях задержка в 2 секунды. На экране будет только Ready: false Loading: true {}:

Затем начнет выполняться промис. Пока он не выполнился отображаться будет то же самое. А затем загрузятся и отобразятся данные:

Появились значения userId:1 id: 1 и другие данные, а индикаторы загрузки сменили значение Ready: true.
Затем, если мы нажмем кнопку Execute, то будет вызвана функция execute, которая сначала выждет свою задержку (но она также указана величиной в 2 секунды) и выполнит промис передав новые аргументы { id: 2 }. Пока промис не выполнился будут отображаться старые данные. Хотя в нашем шаблоне изменяется индикаторы загрузки на  Ready: false Loading: true. После загрузки вместе со сменой значений индикаторов мы увидим новые данные. Значение id = 2 и другое значение для title:

Это похоже на работу библиотеки TanStack Query (Vue Query), описанной в предыдущей статье.
VueUse содержит очень много различных утилит решающих задачи в совершенно разных областях. Думаю, что любой разработчик может найти много полезных инструментов, если уделит некоторое время знакомству с возможностями этой библиотеки.
При чтении документации, правда, приходится много чего смотреть в исходном коде. Это по началу может мешать. Часто переключаться между документацией и исходным кодом не так удобно. Но скоро привыкаешь и начинаешь быстро находить нужные ответы.
Также существующая разбивка коллекции VueUse на группы функций кажется не всегда логичной и достаточной. Но, вероятно, со временем там будет больше порядка.
В целом присмотреться к этому набору инструментов не будет лишним. Будет интересно увидеть в комментариях какие из утилит VueUse используете вы и для чего.