VueUse

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 {}:

Начальный экран примера useAsyncState

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

Экран примера useAsyncState после выполнения промиса

Появились значения userId:1 id: 1 и другие данные, а индикаторы загрузки сменили значение Ready: true.

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

Экран примера useAsyncState после нажатия кнопки и выполнения промиса с новыми параметрами

Это похоже на работу библиотеки TanStack Query (Vue Query), описанной в предыдущей статье.

VueUse содержит очень много различных утилит решающих задачи в совершенно разных областях. Думаю, что любой разработчик может найти много полезных инструментов, если уделит некоторое время знакомству с возможностями этой библиотеки.

При чтении документации, правда, приходится много чего смотреть в исходном коде. Это по началу может мешать. Часто переключаться между документацией и исходным кодом не так удобно. Но скоро привыкаешь и начинаешь быстро находить нужные ответы.

Также существующая разбивка коллекции VueUse на группы функций кажется не всегда логичной и достаточной. Но, вероятно, со временем там будет больше порядка.

В целом присмотреться к этому набору инструментов не будет лишним. Будет интересно увидеть в комментариях какие из утилит VueUse используете вы и для чего.

Оставить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *