Система иконок в Vuetify построена на абстракции над различными наборами иконок. Компоненты интерфейса не зависят напрямую от конкретной библиотеки — вместо этого используется единый механизм рендеринга иконок, который может работать с Material Design Icons, Font Awesome, SVG-иконками, иконками из файлов, а также с полностью кастомными компонентами.
Базовым элементом системы является компонент
v-icon, который отвечает за отображение
иконок в интерфейсе. Он используется напрямую или внутри других
компонентов:
v-btnv-list-itemv-navigation-drawerv-text-fieldv-tabsv-chipv-toolbarVuetify предоставляет механизм регистрации кастомных иконок, позволяющий:
v-iconКомпонент v-icon является универсальным контейнером для
отображения иконок.
Простейшее использование:
<v-icon>mdi-home</v-icon>
Vuetify определяет активный набор иконок и отображает нужный символ.
Возможные варианты:
<v-icon icon="mdi-account"></v-icon>
<v-icon size="24">
mdi-settings
</v-icon>
<v-icon color="red">
mdi-alert
</v-icon>
Основные свойства компонента:
| Свойство | Описание |
|---|---|
icon |
имя иконки |
size |
размер иконки |
color |
цвет |
start / end |
позиционирование внутри компонентов |
tag |
HTML-тег контейнера |
Пример с кнопкой:
<v-btn>
<v-icon start>mdi-plus</v-icon>
Добавить
</v-btn>
В Vuetify 3 настройка иконок выполняется при создании экземпляра фреймворка.
import { createVuetify } from 'vuetify'
export default createVuetify({
icons: {
defaultSet: 'mdi'
}
})
Параметр icons содержит:
| Параметр | Назначение |
|---|---|
defaultSet |
основной набор иконок |
sets |
зарегистрированные наборы |
aliases |
псевдонимы иконок |
Vuetify активно использует aliases — имена-псевдонимы для иконок, используемых внутри компонентов.
Например:
closemenusuccesserrorprevnextAlias связывает внутреннее имя Vuetify с конкретной иконкой.
Пример настройки:
import { aliases } from 'vuetify/iconsets/mdi'
createVuetify({
icons: {
defaultSet: 'mdi',
aliases
}
})
Кастомный alias:
createVuetify({
icons: {
aliases: {
dashboard: 'mdi-view-dashboard'
}
}
})
Использование:
<v-icon icon="dashboard"></v-icon>
Vuetify позволяет регистрировать собственные наборы.
Структура набора:
const customSet = {
component: (props) => h(...)
}
Регистрация:
createVuetify({
icons: {
defaultSet: 'custom',
sets: {
custom: customSet
}
}
})
После регистрации:
<v-icon icon="custom:home"></v-icon>
Префикс указывает Vuetify использовать конкретный набор.
Наиболее распространённый способ создания собственных иконок — использование SVG.
SVG можно встроить прямо в компонент.
import { h } from 'vue'
const MyIcon = {
component: (props) => {
return h(
'svg',
{
viewBox: '0 0 24 24',
width: props.size,
height: props.size
},
[
h('path', {
d: 'M12 2L2 7h20L12 2z'
})
]
)
}
}
Регистрация:
createVuetify({
icons: {
sets: {
custom: {
component: MyIcon
}
}
}
})
Использование:
<v-icon icon="custom"></v-icon>
Vuetify поддерживает регистрацию Vue-компонентов в качестве иконок.
Создание компонента:
// icons/StarIcon.vue
<template>
<svg viewBox="0 0 24 24">
<path d="M12 2L15 9H22L17 13L19 21L12 17L5 21L7 13L2 9H9Z"/>
</svg>
</template>
Регистрация:
import StarIcon from '@/icons/StarIcon.vue'
createVuetify({
icons: {
aliases: {
star: StarIcon
}
}
})
Использование:
<v-icon icon="star"></v-icon>
Иконки можно импортировать напрямую из SVG-файлов.
import MyIcon from '@/assets/icons/custom.svg'
Регистрация:
createVuetify({
icons: {
aliases: {
customIcon: MyIcon
}
}
})
Использование:
<v-icon icon="customIcon"></v-icon>
Такой подход требует соответствующей конфигурации сборщика (Vite / Webpack).
Компоненты Vuetify используют alias-иконки. Их можно заменить.
Пример: замена иконки закрытия.
createVuetify({
icons: {
aliases: {
close: 'mdi-close-circle'
}
}
})
Теперь все компоненты будут использовать новую иконку:
v-dialogv-snackbarv-chipИногда требуется создать целую библиотеку иконок.
icons/
home.svg
user.svg
settings.svg
Создание набора:
import HomeIcon from '@/icons/home.svg'
import UserIcon from '@/icons/user.svg'
import SettingsIcon from '@/icons/settings.svg'
const customIcons = {
home: HomeIcon,
user: UserIcon,
settings: SettingsIcon
}
Регистрация:
createVuetify({
icons: {
defaultSet: 'custom',
sets: {
custom: {
component: (props) => {
const Icon = customIcons[props.icon]
return h(Icon)
}
}
}
}
})
Использование:
<v-icon icon="home"></v-icon>
<v-icon icon="user"></v-icon>
Для крупных проектов удобно создать централизованный файл иконок.
src/icons/index.js
import Dashboard from './dashboard.svg'
import User from './user.svg'
import Settings from './settings.svg'
export default {
dashboard: Dashboard,
user: User,
settings: Settings
}
Подключение:
import icons from '@/icons'
createVuetify({
icons: {
aliases: icons
}
})
Это позволяет:
Иконку можно выбирать динамически.
<v-icon :icon="currentIcon"></v-icon>
const currentIcon = ref('mdi-home')
Изменение значения:
currentIcon.value = 'mdi-account'
<v-icon v-if="isOpen">
mdi-chevron-up
</v-icon>
<v-icon v-else>
mdi-chevron-down
</v-icon>
Или:
<v-icon :icon="isOpen ? 'mdi-eye' : 'mdi-eye-off'"></v-icon>
Иконки можно стилизовать через CSS.
<v-icon class="custom-icon">
mdi-heart
</v-icon>
.custom-icon {
font-size: 32px;
color: #ff4081;
}
SVG-иконки поддерживают:
fillstrokeopacityПример:
svg {
fill: currentColor;
}
Использование currentColor позволяет иконке
автоматически наследовать цвет текста.
При использовании кастомных иконок важно учитывать производительность.
Основные рекомендации:
Использование SVG вместо шрифтов
SVG:
Tree-shaking
Импорт только используемых иконок:
import { mdiAccount } from '@mdi/js'
Lazy loading
Для больших наборов иконок можно применять динамический импорт:
const icon = await import(`@/icons/${name}.svg`)
Полная настройка кастомных иконок:
import { createVuetify } from 'vuetify'
import DashboardIcon from '@/icons/dashboard.svg'
import UserIcon from '@/icons/user.svg'
const aliases = {
dashboard: DashboardIcon,
user: UserIcon
}
export default createVuetify({
icons: {
defaultSet: 'custom',
aliases
}
})
Использование в интерфейсе:
<v-btn>
<v-icon start icon="dashboard"></v-icon>
Панель
</v-btn>
<v-list-item>
<v-icon start icon="user"></v-icon>
Профиль
</v-list-item>
SVG должен иметь корректный viewBox.
Правильно:
<svg viewBox="0 0 24 24">
Без viewBox масштабирование работать не будет.
currentColorЕсли SVG содержит фиксированный цвет:
fill="#000"
иконка не будет менять цвет через Vuetify.
Правильно:
fill="currentColor"
Если используется несколько наборов:
<v-icon icon="mdi:home"></v-icon>
<v-icon icon="fa:user"></v-icon>
нужно явно указывать префикс.
SVG-иконки часто содержат лишние данные:
Оптимизация выполняется через SVGO.
Рекомендуемая структура:
src/
icons/
navigation/
actions/
status/
index.js
Это позволяет:
Иконки можно инкапсулировать внутри компонентов.
<template>
<v-btn>
<v-icon start icon="mdi-download"/>
Скачать
</v-btn>
</template>
Компонент становится переиспользуемым:
DownloadButton.vue
Такой подход: