Гид по технологиям

Iconify в Vue 3 — интеграция и лучшие практики

7 min read Frontend Обновлено 17 Dec 2025
Iconify в Vue 3 — интеграция и лучшие практики
Iconify в Vue 3 — интеграция и лучшие практики

Набор разных иконок на экране

Кратко

Iconify — это универсальная коллекция SVG-иконок и набор инструментов для их использования в веб-приложениях. В статье показано, как подключить Iconify в Vue 3 с помощью пакета @iconify/vue и альтернативного подхода через unplugin-icons, как избежать проблем рендеринга и как сделать иконки доступными и оптимизированными.

Лучшие веб-приложения используют тексты и изображения вместе — иконки дают визуальные подсказки, ускоряют восприятие интерфейса и повышают вовлечённость. Iconify объединяет множество наборов иконок (Material, Bootstrap, Phosphor и др.) и предоставляет пути интеграции для современных фронтенд‑фреймворков, включая Vue.

Что такое Iconify и когда он нужен

Iconify — это фреймворк для иконок, который предоставляет:

  • большую коллекцию SVG-иконок из разных наборов;
  • поддержку динамической загрузки иконок и пакетирования;
  • интеграции для Vue, React и других инструментов.

Когда использовать Iconify:

  • нужны SVG‑иконки разных стилей и наборов;
  • требуется гибкая кастомизация цвета/размера/трансформаций в шаблонах Vue;
  • нужно снизить ручную работу по управлению SVG-ассетами.

Когда лучше рассмотреть альтернативы:

  • если у вас единый фирменный набор и вы хотите полностью контролировать сборку — тогда имеет смысл собрать собственный SVG‑спрайт или компонент‑набор;
  • если важен минимальный размер бандла и вы не хотите устанавливать большие JSON‑паки;
  • для старых проектов на Vue 2 можно использовать отдельную обёртку @iconify/vue2.

TL;DR: краткая инструкция по установке и быстрому использованию

  • Для Vue 3 установите пакет: npm install –save-dev @iconify/vue
  • Импортируйте компонент Icon и используйте в шаблоне:
  • Если сталкиваетесь с проблемами рендеринга или хотите локально бандлить иконки — используйте unplugin-icons + @iconify/json.
  • Не забывайте про доступность: aria-hidden, role, title/desc или скрытые подписи для скрин‑ридеров.

Установка @iconify/vue (Vue 3)

Пакет @iconify/vue — это официальная интеграция Iconify для Vue 3. Установите его в директории приложения:

npm install --save-dev @iconify/vue

Если у вас всё ещё проект на Vue 2, используйте альтернативный пакет:

npm install @iconify/vue2

Важно: официальный пакет @iconify/vue предназначен для Vue 3. Поддержка Vue 2 прекращается, поэтому для новых проектов стоит мигрировать на Vue 3.

Быстрое добавление иконки в компонент Vue

  1. Импортируйте компонент Icon в блоке скрипта вашего SFC:
  1. Используйте компонент в шаблоне, указывая идентификатор иконки и параметры:

Идентификатор иконки состоит из префикса набора (ph — Phosphor) и имени иконки через двоеточие.

Интерфейс сайта Iconify с поиском иконок

На сайте Iconify можно найти нужную иконку и скопировать её идентификатор или код‑фрагмент для вставки.

Результаты поиска значка

Превью красной галочки

Частые проблемы с рендерингом и их причины

Некоторые разработчики сталкиваются с ситуациями, когда иконки не рендерятся корректно, появляются ошибки в DOM или иконки не гидрируются при SSR/пререндеринге. Основные причины:

  • порядок инициализации компонентов и загрузки внешних ресурсов;
  • динамическая подгрузка иконок после монтирования компонента;
  • особенности сборщика (Vite/Rollup/Webpack) и конфигурации плагинов.

Если вы видите ошибки, проверьте последовательность импорта, используете ли вы серверный рендеринг и не блокируют ли политики CSP загрузку ресурсов.

Альтернативный способ: unplugin-icons (локальная компиляция иконок)

unplugin-icons позволяет импортировать иконки как компоненты во время сборки, что устраняет проблемы времени выполнения и упрощает контроль над бандлом.

  1. Установите плагин:
npm install unplugin-icons
  1. Для проекта на Vite отредактируйте vite.config.js, добавив плагин:
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Icons from 'unplugin-icons/vite'

export default defineConfig({
  plugins: [vue(), Icons()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})
  1. (Опционально) Установите наборы иконок в виде JSON, если хотите иметь все наборы локально:
npm i -D @iconify/json

В исходной документации указывается, что полный пакет @iconify/json занимает около 200 МБ. Чтобы уменьшить размер, можно установить только конкретный набор, например Phosphor:

npm i -D @iconify-json/ph
  1. Импортируйте иконку как компонент через псевдопуть ~icons:


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

Доступность (a11y) и лучшие практики

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

  • Декоративные иконки: добавляйте aria-hidden=”true” и role=”img” при необходимости, чтобы скрин‑ридеры их игнорировали.
  • Иконки, несущие смысл: предоставляйте текстовую альтернативу — либо через aria-label, либо совместно с видимым текстом.
  • SVG внутри компонента: используйте и <desc> внутри SVG, если требуется более подробное описание.</li></ul><p class="">Пример декоративной иконки:</p><div class="code-ui group"><pre class=""><code class="vue" class=""><Icon icon="ph:star" aria-hidden="true" /></code></pre></div><p class="">Пример значимой иконки с подписью:</p><div class="code-ui group"><pre class=""><code class="vue" class=""><Icon icon="ph:info" aria-label="Информация о версии" /> <span class="sr-only">Информация о версии</span></code></pre></div><p class="">Совет: класс .sr-only (screen reader only) скрывает текст визуально, но делает его доступным для скрин‑ридеров.</p><h2 class="text-2xl font-bold py-2" id="h2-7">Стратегии оптимизации и размер бандла</h2><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Используйте unplugin-icons или локальный набор @iconify-json, если хотите контролировать размер бандла.</li><li class="">Не добавляйте все наборы @iconify/json в проект, если используете несколько иконок — выбирайте только нужные наборы.</li><li class="">При динамической подгрузке иконок проверьте политику кэширования и CDN, чтобы снизить сетевые задержки.</li></ul><h2 class="text-2xl font-bold py-2" id="h2-8">Модели мышления и практические эвристики</h2><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">“Single source of truth”: определите одно место, где управляются все иконки (компонент-обёртка или дизайн‑система).</li><li class="">“Progressive enhancement”: предоставляйте семантические подписи для ключевых иконок и делайте декоративные иконки невидимыми для вспомогательных технологий.</li><li class="">“Bundle by feature”: вместо глобальной установки всех наборов, импортируйте иконки по функциям (feature-based imports).</li></ul><h2 class="text-2xl font-bold py-2" id="h2-9">Контроль качества: тесты и критерии приёмки</h2><p class="">Критерии приёмки для страницы/компонента с иконками:</p><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Иконки отображаются на основных целевых устройствах и разрешениях.</li><li class="">Иконки имеют корректные aria-атрибуты (декоративные скрыты, значимые — доступны).</li><li class="">При отключённом JavaScript или в режиме пререндеринга интерфейс остаётся работоспособным (ключевой функционал не зависит от динамической подгрузки иконок).</li><li class="">Не появляется ошибок в консоли, связанных с загрузкой и рендерингом иконок.</li></ul><p class="">Минимальные тест‑кейсы:</p><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Рендер компонента с несколькими иконками — визуальная сверка.</li><li class="">Прослушивание изменений: изменение цвета/размера через props — проверка эффекта.</li><li class="">Проверка доступности с помощью axe или Lighthouse.</li></ul><h2 class="text-2xl font-bold py-2" id="h2-10">Роль‑ориентированные чек‑листы</h2><p class="">Для разработчика:</p><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Установить пакет (@iconify/vue или unplugin-icons).</li><li class="">Импортировать иконки по соглашению (~icons/{set}/{icon}).</li><li class="">Настроить Vite/webpack плагин при необходимости.</li><li class="">Проверить bundle analyzer и размер бандла.</li></ul><p class="">Для дизайнера:</p><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Выбрать единый набор иконок или наборы, которые подходят под визуальный стиль.</li><li class="">Предоставить имена иконок и рекомендации по размерам/контрасту.</li></ul><p class="">Для ревьювера и QA:</p><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Проверить ARIA‑метки и видимость для скрин‑ридеров.</li><li class="">Проверить соответствие иконок дизайн‑гайдам.</li><li class="">Запустить Lighthouse/Axe и устранить критические проблемы.</li></ul><h2 class="text-2xl font-bold py-2" id="h2-11">Миграция с Vue 2 на Vue 3 и совместимость</h2><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Для проектов на Vue 2 используйте @iconify/vue2 до миграции.</li><li class="">Планируйте переход на Vue 3 и @iconify/vue, чтобы использовать последние улучшения и плагины.</li><li class="">При миграции проверьте:<ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">совместимость плагинов сборки;</li><li class="">изменения в дереве компонентов (composition API и script setup);</li><li class="">тесты на рендеринг и гидрацию.</li></ul></li></ul><h2 class="text-2xl font-bold py-2" id="h2-12">Отладка и распространённые ошибки — как исправлять</h2><p class="">Симптом: иконка не отображается, в консоли ошибка.</p><p class="">Проверки:</p><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Правильно ли указан идентификатор (например, ph:check-fill)?</li><li class="">Импортирован ли компонент Icon или локальный компонент из ~icons?</li><li class="">Не блокирует ли CSP загрузку внешних ресурсов?</li><li class="">Если используете SSR/пререндер — есть ли отличия во времени загрузки инициализации?</li></ul><p class="">Решения:</p><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Для проблем времени выполнения — используйте unplugin-icons, чтобы собрать иконки на этапе сборки.</li><li class="">Для проблем CSP — включите необходимые хосты или используйте локальные ассеты.</li></ul><h2 class="text-2xl font-bold py-2" id="h2-13">Сравнение подходов (кратко)</h2><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">@iconify/vue: простая интеграция, динамическая загрузка иконок.</li><li class="">unplugin-icons + @iconify-json: локальная сборка иконок, предсказуемый бандл.</li><li class="">SVG‑спрайт: полный контроль, минимальные зависимости, но больше ручной работы.</li><li class="">Иконки‑шрифты: устаревшая техника, проще в использовании, но хуже в доступности и качестве масштабирования.</li></ul><h2 class="text-2xl font-bold py-2" id="h2-14">Пример рабочего мини‑workflow для новой фичи</h2><ol class="my-6 space-y-2 list-decimal pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Дизайнер выбирает иконки и передаёт список.</li><li class="">Разработчик импортирует нужные иконки (через ~icons или @iconify/vue).</li><li class="">QA проверяет отображение, доступность и bundle size.</li><li class="">В релизе отслеживать пользовательские отчёты и метрики визуальных багов.</li></ol><p class="">Mermaid-диаграмма принятия решения (упрощённая):</p><div class=""><pre class="not-prose"><code class="mermaid" class="">graph TD A[Нужны иконки в проекте?] -->|Да| B{Использовать локальную сборку?} B -->|Да| C[unplugin-icons + @iconify-json] B -->|Нет| D[@iconify/vue 'динамическая'] A -->|Нет| E[Не использовать сторонние иконки]</code></pre></div><h2 class="text-2xl font-bold py-2" id="h2-15">Заключение</h2><p class="">Iconify даёт гибкие варианты интеграции и большой выбор иконок. Для большинства Vue 3‑проектов достаточно @iconify/vue для быстрого старта, но при требованиях к производительности и предсказуемости сборки лучше использовать unplugin-icons и локальные JSON‑набoры. Не забывайте о доступности и контроле размера бандла — это ключ к качественному пользовательскому опыту.</p><p class="">Ключевые советы:</p><ul class="my-6 list-disc space-y-2 pl-6 md:pl-8 [&_li]:marker:text-slate-400"><li class="">Выберите стратегию импорта (динамическая или на этапе сборки) заранее.</li><li class="">Ограничьте наборы иконок по необходимости.</li><li class="">Тестируйте доступность и поведение при SSR.</li></ul> </div> </div> <div class="mt-8"> <div class="flex flex-wrap items-center gap-2"> <span class="text-sm text-slate-600 dark:text-slate-300">Поделиться:</span> <a href="https://twitter.com/intent/tweet?url=https://techhaps.com/ru/p/what-is-iconify-how-to-integrate-it-in-vue-apps-96486688&text=Iconify%20%D0%B2%20Vue%203%20%E2%80%94%20%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F%20%D0%B8%20%D0%BB%D1%83%D1%87%D1%88%D0%B8%D0%B5%20%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D0%B8" target="_blank" class="rounded-xl border border-slate-300 px-3 py-1.5 text-sm hover:bg-slate-50 dark:border-slate-700 dark:hover:bg-slate-800"> X/Twitter </a> <a href="https://www.facebook.com/sharer/sharer.php?u=https://techhaps.com/ru/p/what-is-iconify-how-to-integrate-it-in-vue-apps-96486688" target="_blank" class="rounded-xl border border-slate-300 px-3 py-1.5 text-sm hover:bg-slate-50 dark:border-slate-700 dark:hover:bg-slate-800"> Facebook </a> <a href="https://www.linkedin.com/sharing/share-offsite/?url=https://techhaps.com/ru/p/what-is-iconify-how-to-integrate-it-in-vue-apps-96486688" target="_blank" class="rounded-xl border border-slate-300 px-3 py-1.5 text-sm hover:bg-slate-50 dark:border-slate-700 dark:hover:bg-slate-800"> LinkedIn </a> <a href="https://t.me/share/url?url=https://techhaps.com/ru/p/what-is-iconify-how-to-integrate-it-in-vue-apps-96486688&text=Iconify%20%D0%B2%20Vue%203%20%E2%80%94%20%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F%20%D0%B8%20%D0%BB%D1%83%D1%87%D1%88%D0%B8%D0%B5%20%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D0%B8" target="_blank" class="rounded-xl border border-slate-300 px-3 py-1.5 text-sm hover:bg-slate-50 dark:border-slate-700 dark:hover:bg-slate-800"> Telegram </a> <button type="button" id="copyLink" data-url="https://techhaps.com/ru/p/what-is-iconify-how-to-integrate-it-in-vue-apps-96486688" class="rounded-xl border border-slate-300 px-3 py-1.5 text-sm hover:bg-slate-50 dark:border-slate-700 dark:hover:bg-slate-800 cursor-pointer"> Скопировать ссылку </button> </div> </div> <div class="mt-10 rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-5 flex items-center gap-4"> <img src="/images/avatar-78998a9e25a46e051fea19306867798d.svg?vsn=d" alt="" class="h-12 w-12 rounded-full ring-1 ring-slate-200 dark:ring-slate-700" loading="lazy"> <div> <div class="text-sm text-slate-500">Автор</div> <div class="text-base font-semibold text-slate-900 dark:text-white"> Редакция </div> </div> </div> <nav class="mt-10 grid gap-4 md:grid-cols-2"> <a href="/ru/p/how-to-enable-or-disable-the-adaptive-brightness-on-steam-deck-659478" class="group rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-4 hover:bg-slate-50/70 dark:hover:bg-slate-800/50 transition"> <div class="text-xs text-slate-500">Предыдущая статья</div> <div class="mt-1 font-semibold text-slate-900 dark:text-white line-clamp-2 group-hover:text-indigo-600"> Адаптивная яркость на Steam Deck — включение и советы </div> </a> <a href="/ru/p/how-to-react-to-messages-on-instagram-100296064" class="group rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-4 hover:bg-slate-50/70 dark:hover:bg-slate-800/50 transition"> <div class="text-xs text-slate-500">Следующая статья</div> <div class="mt-1 font-semibold text-slate-900 dark:text-white line-clamp-2 group-hover:text-indigo-600"> Как реагировать на сообщения в Instagram </div> </a> </nav> <div class="mt-12"> <h2 class="text-xl md:text-2xl font-bold tracking-tight text-slate-900 dark:text-white"> Похожие материалы </h2> <div class="mt-4 grid grid-cols-1 sm:grid-cols-2 gap-4"> <article class="group relative grid grid-cols-[96px_1fr] gap-4 rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-3 hover:bg-slate-50/70 dark:hover:bg-slate-800/50 transition"> <a href="/ru/p/how-to-make-your-iphone-use-jpg-and-mp4-files-instead-of-heif-heic-and-hevc-7604167" class="absolute inset-0 z-10" aria-label="iPhone: Снимать в совместимых форматах (JPEG/MP4)"> </a> <div class="overflow-hidden rounded-xl"> <img src="/files/59305195-1b60-43a3-9eb9-23c90ec3ec97.jpg" alt="iPhone: Снимать в совместимых форматах (JPEG/MP4)" class="h-24 w-full object-cover" loading="lazy"> </div> <div class="min-w-0"> <div class="mb-1 flex items-center gap-2"> <span class="inline-flex items-center rounded-full bg-slate-100 dark:bg-slate-800 px-2.5 py-1 text-xs font-medium text-slate-700 dark:text-slate-200 ring-1 ring-inset ring-slate-200/60 dark:ring-slate-700/60"> Гайд </span> <time class="text-xs text-slate-500">17 Dec 2025</time> </div> <h3 class="text-sm font-semibold text-slate-900 dark:text-white line-clamp-2"> iPhone: Снимать в совместимых форматах (JPEG/MP4) </h3> </div> </article> <article class="group relative grid grid-cols-[96px_1fr] gap-4 rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-3 hover:bg-slate-50/70 dark:hover:bg-slate-800/50 transition"> <a href="/ru/p/how-to-make-windows-play-a-sound-when-you-press-caps-lock-num-lock-or-scroll-lock-7233959" class="absolute inset-0 z-10" aria-label="Звук при нажатии Caps/Num/Scroll Lock в Windows"> </a> <div class="overflow-hidden rounded-xl"> <img src="/files/3757a466-32f8-4643-94ae-54d54e920fb0.png" alt="Звук при нажатии Caps/Num/Scroll Lock в Windows" class="h-24 w-full object-cover" loading="lazy"> </div> <div class="min-w-0"> <div class="mb-1 flex items-center gap-2"> <span class="inline-flex items-center rounded-full bg-slate-100 dark:bg-slate-800 px-2.5 py-1 text-xs font-medium text-slate-700 dark:text-slate-200 ring-1 ring-inset ring-slate-200/60 dark:ring-slate-700/60"> Windows </span> <time class="text-xs text-slate-500">17 Dec 2025</time> </div> <h3 class="text-sm font-semibold text-slate-900 dark:text-white line-clamp-2"> Звук при нажатии Caps/Num/Scroll Lock в Windows </h3> </div> </article> <article class="group relative grid grid-cols-[96px_1fr] gap-4 rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-3 hover:bg-slate-50/70 dark:hover:bg-slate-800/50 transition"> <a href="/ru/p/how-to-remove-paired-bluetooth-devices-on-android-7479551" class="absolute inset-0 z-10" aria-label="Сброс Bluetooth на Android: удалить пары и кэш"> </a> <div class="overflow-hidden rounded-xl"> <img src="/files/f5e7368f-f10f-43df-9e81-17fc3bc48a97.jpg" alt="Сброс Bluetooth на Android: удалить пары и кэш" class="h-24 w-full object-cover" loading="lazy"> </div> <div class="min-w-0"> <div class="mb-1 flex items-center gap-2"> <span class="inline-flex items-center rounded-full bg-slate-100 dark:bg-slate-800 px-2.5 py-1 text-xs font-medium text-slate-700 dark:text-slate-200 ring-1 ring-inset ring-slate-200/60 dark:ring-slate-700/60"> Android. </span> <time class="text-xs text-slate-500">17 Dec 2025</time> </div> <h3 class="text-sm font-semibold text-slate-900 dark:text-white line-clamp-2"> Сброс Bluetooth на Android: удалить пары и кэш </h3> </div> </article> <article class="group relative grid grid-cols-[96px_1fr] gap-4 rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-3 hover:bg-slate-50/70 dark:hover:bg-slate-800/50 transition"> <a href="/ru/p/how-to-add-favicons-to-safari-on-macos-7407267" class="absolute inset-0 z-10" aria-label="Faviconographer — фавиконы для Safari на Mac"> </a> <div class="overflow-hidden rounded-xl"> <img src="/files/9896aa0d-2410-42fa-a36b-2930bf0aeb88.png" alt="Faviconographer — фавиконы для Safari на Mac" class="h-24 w-full object-cover" loading="lazy"> </div> <div class="min-w-0"> <div class="mb-1 flex items-center gap-2"> <span class="inline-flex items-center rounded-full bg-slate-100 dark:bg-slate-800 px-2.5 py-1 text-xs font-medium text-slate-700 dark:text-slate-200 ring-1 ring-inset ring-slate-200/60 dark:ring-slate-700/60"> Mac </span> <time class="text-xs text-slate-500">17 Dec 2025</time> </div> <h3 class="text-sm font-semibold text-slate-900 dark:text-white line-clamp-2"> Faviconographer — фавиконы для Safari на Mac </h3> </div> </article> <article class="group relative grid grid-cols-[96px_1fr] gap-4 rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-3 hover:bg-slate-50/70 dark:hover:bg-slate-800/50 transition"> <a href="/ru/p/how-to-turn-on-the-flashlight-by-tapping-your-iphones-back-7115724" class="absolute inset-0 z-10" aria-label="Включить фонарик iPhone касанием"> </a> <div class="overflow-hidden rounded-xl"> <img src="/files/6751d3e5-f278-4c6f-adcc-fa734971b2ab.png" alt="Включить фонарик iPhone касанием" class="h-24 w-full object-cover" loading="lazy"> </div> <div class="min-w-0"> <div class="mb-1 flex items-center gap-2"> <span class="inline-flex items-center rounded-full bg-slate-100 dark:bg-slate-800 px-2.5 py-1 text-xs font-medium text-slate-700 dark:text-slate-200 ring-1 ring-inset ring-slate-200/60 dark:ring-slate-700/60"> Инструкции </span> <time class="text-xs text-slate-500">17 Dec 2025</time> </div> <h3 class="text-sm font-semibold text-slate-900 dark:text-white line-clamp-2"> Включить фонарик iPhone касанием </h3> </div> </article> <article class="group relative grid grid-cols-[96px_1fr] gap-4 rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-3 hover:bg-slate-50/70 dark:hover:bg-slate-800/50 transition"> <a href="/ru/p/how-to-set-up-and-use-a-passcode-on-apple-watch-7943548" class="absolute inset-0 z-10" aria-label="Код‑пароль на Apple Watch: настройка и советы"> </a> <div class="overflow-hidden rounded-xl"> <img src="/files/0a9261dd-be50-41d8-8b3e-6bf896920ea6.png" alt="Код‑пароль на Apple Watch: настройка и советы" class="h-24 w-full object-cover" loading="lazy"> </div> <div class="min-w-0"> <div class="mb-1 flex items-center gap-2"> <span class="inline-flex items-center rounded-full bg-slate-100 dark:bg-slate-800 px-2.5 py-1 text-xs font-medium text-slate-700 dark:text-slate-200 ring-1 ring-inset ring-slate-200/60 dark:ring-slate-700/60"> Руководство </span> <time class="text-xs text-slate-500">17 Dec 2025</time> </div> <h3 class="text-sm font-semibold text-slate-900 dark:text-white line-clamp-2"> Код‑пароль на Apple Watch: настройка и советы </h3> </div> </article> </div> </div> </div> <div class="hidden lg:block"> <aside class="lg:sticky lg:top-24"> <div class="rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-4"> <h2 class="text-sm font-semibold text-slate-900 dark:text-white"> Содержание </h2> <ul class="mt-3 space-y-1 text-sm"> <li class="leading-5 ml-0"> <a href="#h2-0" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Что такое Iconify и когда он нужен </a> </li> <li class="leading-5 ml-0"> <a href="#h2-1" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> TL;DR: краткая инструкция по установке и быстрому использованию </a> </li> <li class="leading-5 ml-0"> <a href="#h2-2" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Установка @iconify/vue (Vue 3) </a> </li> <li class="leading-5 ml-0"> <a href="#h2-3" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Быстрое добавление иконки в компонент Vue </a> </li> <li class="leading-5 ml-0"> <a href="#h2-4" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Частые проблемы с рендерингом и их причины </a> </li> <li class="leading-5 ml-0"> <a href="#h2-5" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Альтернативный способ: unplugin-icons (локальная компиляция иконок) </a> </li> <li class="leading-5 ml-0"> <a href="#h2-6" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Доступность (a11y) и лучшие практики </a> </li> <li class="leading-5 ml-0"> <a href="#h2-7" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Стратегии оптимизации и размер бандла </a> </li> <li class="leading-5 ml-0"> <a href="#h2-8" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Модели мышления и практические эвристики </a> </li> <li class="leading-5 ml-0"> <a href="#h2-9" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Контроль качества: тесты и критерии приёмки </a> </li> <li class="leading-5 ml-0"> <a href="#h2-10" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Роль‑ориентированные чек‑листы </a> </li> <li class="leading-5 ml-0"> <a href="#h2-11" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Миграция с Vue 2 на Vue 3 и совместимость </a> </li> <li class="leading-5 ml-0"> <a href="#h2-12" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Отладка и распространённые ошибки — как исправлять </a> </li> <li class="leading-5 ml-0"> <a href="#h2-13" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Сравнение подходов (кратко) </a> </li> <li class="leading-5 ml-0"> <a href="#h2-14" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Пример рабочего мини‑workflow для новой фичи </a> </li> <li class="leading-5 ml-0"> <a href="#h2-15" class="block rounded px-2 py-1 text-slate-600 hover:text-indigo-600 dark:text-slate-300"> Заключение </a> </li> </ul> </div> </aside> </div> </div> </article> </main> <footer class="mt-10 border-t border-zinc-200 dark:border-zinc-800"> <div class="mx-auto max-w-7xl px-4 py-10 text-sm text-zinc-500 grid md:grid-cols-2 align-middle"> <div> <img src="/logo.svg" alt="Гид по технологиям" width="280" height="40" class="w-full md:w-[280px]"> </div> <div class="mt-4 md:mt-0"> <ul> <li class="mt-1"> <a href="/about" class="hover:underline">О нас</a> </li> <li class="mt-1"> <a href="/privacy" class="hover:underline"> Политика конфиденциальности </a> </li> <li class="mt-1"> <a href="/ru/feed" class="hover:underline"> Лента статей </a> </li> </ul> <div class="mt-1"> © 2025 Iconify в Vue 3 — быстрое руководство </div> </div> </div> </footer> </body> </html>