QBtnToggle переключаемые кнопки

QBtnToggle — это компонент библиотеки Quasar, предназначенный для выбора одного значения из набора вариантов с помощью кнопок. Визуально он представляет собой группу кнопок, где активной может быть только одна. Используется как более наглядная и компактная альтернатива выпадающим спискам (QSelect) или радиокнопкам (QRadio).

Компонент особенно полезен в интерфейсах, где важна скорость выбора и визуальная доступность всех опций одновременно.


Базовое использование

Минимальный пример включает привязку значения через v-model и передачу массива опций:

<template>
  <q-btn-toggle
    v-model="model"
    :options="options"
  />
</template>

<script setup>
import { ref } from 'vue'

const model = ref('one')

const options = [
  { label: 'Один', value: 'one' },
  { label: 'Два', value: 'two' },
  { label: 'Три', value: 'three' }
]
</script>

Ключевые моменты:

  • v-model хранит текущее выбранное значение
  • options — массив объектов с параметрами кнопок
  • каждая кнопка соответствует одному значению

Структура опций

Каждый элемент массива options может содержать следующие поля:

Поле Описание
label Текст кнопки
value Значение
icon Иконка
color Цвет кнопки
disable Отключение кнопки

Пример:

const options = [
  { label: 'Список', value: 'list', icon: 'list' },
  { label: 'Сетка', value: 'grid', icon: 'grid_view' },
  { label: 'Карта', value: 'map', icon: 'map', disable: true }
]

Режим обязательного выбора

По умолчанию одна кнопка всегда активна. Чтобы разрешить сброс выбора, используется свойство clearable:

<q-btn-toggle
  v-model="model"
  :options="options"
  clearable
/>

Теперь повторный клик по активной кнопке снимает выбор.


Визуальные настройки

Цвета

<q-btn-toggle
  v-model="model"
  :options="options"
  color="primary"
  text-color="white"
  toggle-color="secondary"
/>
  • color — цвет неактивных кнопок
  • toggle-color — цвет активной кнопки
  • text-color — цвет текста

Плоский, контурный и приподнятый стиль

<q-btn-toggle flat />
<q-btn-toggle outline />
<q-btn-toggle unelevated />
  • flat — без фона
  • outline — только границы
  • unelevated — без тени

Закругление и плотность

<q-btn-toggle
  rounded
  dense
/>
  • rounded — скругленные кнопки
  • dense — уменьшенные отступы

Вертикальное отображение

По умолчанию кнопки располагаются горизонтально. Для вертикального режима:

<q-btn-toggle
  v-model="model"
  :options="options"
  vertical
/>

Управление размером

<q-btn-toggle size="sm" />
<q-btn-toggle size="md" />
<q-btn-toggle size="lg" />

Размер влияет на:

  • высоту кнопок
  • отступы
  • размер текста и иконок

Использование иконок

Кнопки могут содержать только иконки:

const options = [
  { value: 'left', icon: 'arrow_left' },
  { value: 'right', icon: 'arrow_right' }
]

Комбинация текста и иконки:

{ label: 'Назад', value: 'back', icon: 'arrow_back' }

Реактивное поведение

Изменение значения отслеживается стандартным способом:

<q-btn-toggle
  v-model="model"
  :options="options"
/>

<div>{{ model }}</div>

Также можно использовать событие @update:model-value:

<q-btn-toggle
  v-model="model"
  :options="options"
  @update:model-value="onChange"
/>
function onChange(val) {
  console.log('Новое значение:', val)
}

Динамическая генерация опций

Массив кнопок может формироваться динамически:

const modes = ['day', 'week', 'month']

const options = modes.map(mode => ({
  label: mode.toUpperCase(),
  value: mode
}))

Отключение компонента

<q-btn-toggle
  v-model="model"
  :options="options"
  disable
/>

Отключает всю группу кнопок.


Частичное отключение кнопок

const options = [
  { label: 'A', value: 'a' },
  { label: 'B', value: 'b', disable: true }
]

Использование с формами

QBtnToggle интегрируется с QForm:

<q-form @submit="onSubmit">
  <q-btn-toggle
    v-model="model"
    :options="options"
  />

  <q-btn type="submit" label="Отправить" />
</q-form>

Кастомизация через слоты

Компонент поддерживает кастомизацию содержимого кнопок через слот default:

<q-btn-toggle v-model="model" :options="options">
  <template #default="scope">
    <q-btn
      :label="scope.opt.label"
      :icon="scope.opt.icon"
      :color="scope.selected ? 'primary' : 'grey'"
      @click="scope.toggle()"
    />
  </template>
</q-btn-toggle>

scope содержит:

  • opt — текущая опция
  • selected — активна ли кнопка
  • toggle() — функция переключения

Сравнение с альтернативами

Компонент Когда использовать
QBtnToggle Быстрый выбор, визуальные переключатели
QSelect Большое количество опций
QRadio Формы с классическим интерфейсом

Частые сценарии применения

Переключение вида отображения

<q-btn-toggle
  v-model="view"
  :options="[
    { value: 'list', icon: 'list' },
    { value: 'grid', icon: 'grid_view' }
  ]"
/>

Фильтрация данных

<q-btn-toggle
  v-model="status"
  :options="[
    { label: 'Все', value: 'all' },
    { label: 'Активные', value: 'active' },
    { label: 'Завершённые', value: 'done' }
  ]"
/>

Переключение режимов

<q-btn-toggle
  v-model="theme"
  :options="[
    { label: 'Светлая', value: 'light' },
    { label: 'Тёмная', value: 'dark' }
  ]"
/>

Валидация и ограничения

Для ограничения допустимых значений используется логика на уровне v-model:

watch(model, (val) => {
  if (!allowedValues.includes(val)) {
    model.value = 'default'
  }
})

Производительность

Компонент легковесен, но при большом количестве кнопок:

  • увеличивается DOM
  • ухудшается читаемость интерфейса

Рекомендуется:

  • использовать до 5–7 кнопок
  • при большем количестве переходить на QSelect

Особенности поведения

  • всегда работает с одним значением (single-select)
  • порядок кнопок строго соответствует массиву options
  • не поддерживает множественный выбор (для этого используются другие компоненты)

Интеграция с Composition API

import { ref } from 'vue'

export function useToggle(defaultValue) {
  const value = ref(defaultValue)

  const set = (val) => {
    value.value = val
  }

  return {
    value,
    set
  }
}

Использование:

<q-btn-toggle v-model="value" :options="options" />

Расширенные паттерны

Связка с computed

const mode = ref('list')

const isGrid = computed(() => mode.value === 'grid')

Управление через store

const store = useAppStore()

<q-btn-toggle
  v-model="store.viewMode"
  :options="options"
/>

Ограничения и подводные камни

  • отсутствие встроенного multi-select
  • сложность кастомизации без слотов
  • возможная перегруженность UI при большом числе опций
  • необходимость ручного контроля логики при нестандартных сценариях

Практические рекомендации

  • использовать короткие подписи
  • добавлять иконки для повышения читаемости
  • избегать более 5–6 вариантов
  • применять dense в компактных интерфейсах
  • комбинировать с тултипами (QTooltip) при неочевидных значениях

Взаимодействие с другими компонентами Quasar

Часто используется совместно с:

  • QToolbar — переключатели в панели инструментов
  • QCard — управление содержимым карточек
  • QTable — переключение режимов отображения
  • QLayout — изменение глобальных состояний интерфейса

Пример комплексного использования

<template>
  <div>
    <q-btn-toggle
      v-model="view"
      :options="viewOptions"
      toggle-color="primary"
      unelevated
    />

    <div v-if="view === 'list'">Список</div>
    <div v-else-if="view === 'grid'">Сетка</div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const view = ref('list')

const viewOptions = [
  { value: 'list', icon: 'list' },
  { value: 'grid', icon: 'grid_view' }
]
</script>