Skip to content

Интеграция с Vue

Vue composables включены в основной бандл и активируются, когда Vue установлен как peer-зависимость.

Регистрация плагина

ts
import { createApp } from 'vue'
import { ResponsivePlugin } from 'responsive-media'

const app = createApp(App)

app.use(ResponsivePlugin, {
  sm: [{ type: 'max-width', value: 767 }],
  lg: [{ type: 'min-width', value: 1024 }],
})

app.mount('#app')

useResponsive<T>()

Возвращает Vue-реактивное responsive-состояние. Реактивно в шаблонах и computed-свойствах. Принимает обобщённый параметр типа для сужения возвращаемого состояния — см. ConfigToState<T>.

vue
<script setup lang="ts">
import { useResponsive } from 'responsive-media'

type MyState = { sm: boolean; lg: boolean }
const state = useResponsive<MyState>()
</script>

<template>
  <MobileNav v-if="state.sm" />
  <DesktopNav v-else />
</template>

useBreakpoints()

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

vue
<script setup>
import { useBreakpoints } from 'responsive-media'

const { current, isAbove, isBelow, between } = useBreakpoints()
</script>

<template>
  <span>Current: {{ current }}</span>
  <DesktopNav v-if="isAbove('sm')" />
  <MobileNav v-else />
  <TabletOnly v-if="between('sm', 'lg')" />
</template>

current — это ComputedRef<string | null>. isAbove, isBelow, between — обычные функции, реактивные благодаря тому, что читают из Vue-реактивного состояния.

useMediaQuery(query)

Ref<boolean>

Возвращает реактивную ссылку для сырой строки CSS media query. Автоматически убирается при onUnmounted.

vue
<script setup>
import { useMediaQuery } from 'responsive-media'

const isDark = useMediaQuery('(prefers-color-scheme: dark)')
const canHover = useMediaQuery('(hover: hover)')
</script>

<template>
  <DarkTheme v-if="isDark" />
</template>

useContainerState(elementRef, config, options?)

Отслеживает размеры элемента и возвращает объект реактивного состояния. Автоматически настраивает и убирает ResizeObserver через watchEffect.

vue
<script setup>
import { useTemplateRef } from 'vue'
import { useContainerState } from 'responsive-media'

const cardRef = useTemplateRef('card')
const cardState = useContainerState(cardRef, {
  compact: [{ type: 'max-width', value: 300 }],
  wide: [{ type: 'min-width', value: 600 }],
})
</script>

<template>
  <div ref="card">
    <CompactLayout v-if="cardState.compact" />
    <WideLayout v-else-if="cardState.wide" />
    <DefaultLayout v-else />
  </div>
</template>