Задать вопрос
@223606322
начинающий web-разработчик

Как лучше подключать svg иконки во vue js?

Возник вопрос о том как лучше с точки зрения производительности и правильности организации кода подключать svg-иконки? Как это делаете вы?

1 Вариант:
Создать под каждую иконку свой компонент ("Close-icon.vue", "Menu-icon.vue", "Edit-icon.vue") и просто подключать как отдельный компонент.

2 Вариант:
Создать один компонент, например "Icons.vue", внутри добавить пропс name и через условные операторы рендерить необходимую иконку в зависимости от того, что лежит в пропс. Условно, если в пропс передали "close", то в компоненте "Icons.vue", через "v-if/v-else-if" рендерить ту, которая равна "close".

Может есть еще какие-то более лучшие варианты или готовые библиотеки?
  • Вопрос задан
  • 2054 просмотра
Подписаться 2 Простой Комментировать
Решения вопроса 4
@iljaGolubev
Если точно нужны inline svg, то vue-svg-loader - он делает автоматически ваш 1-й вариант.

Ещё есть vite-svg-loader - подключается как плагин к vite и удобен тем, что можно из vite.config менять как импортировать файл (url или raw).

Можно написать свой компонент в который передавать имя иконки. Только не делайте свой 2-й вариант - его недостаток в том, что все иконки всегда загружаются в браузер даже если никогда не будут показаны.

через "v-if/v-else-if" рендерить ту, которая равна "close".

Если у вас всего 2-3 иконки - можно и так, но в общем случае - старайтесь не использовать длинные "портянки" if/else. Почти всегда можно обойтись без такого кода. (conponent is или defineAsyncComponent)
Ответ написан
Комментировать
@Pike-meow
Pike - is a life
На самом деле, решение зависит от ситуации.

Если у вас есть не огромный(!) набор иконок для повсеместного использования - то вам нужен SVG Sprite. В других ответах уже накидали даже названий библиотек для Vue.

Если коротко, то использование выглядит следующим образом:

Кладете в public файл со спрайтами (обычно, сборка такого файла берут на себя библиотеки. Не хитрый SVG файл, который можно один раз собрать и юзать сборку)

А далее - элементарный компонент

Icon.vue
<template>
  <svg>
    <use :xlink:href="`path-to-sprite.svg#${iconName}`"></use>
  </svg>
</template>

<script lang="ts" setup>
  defineProps<{
    iconName: string;
  }>();
</script>


Использования будет выглядеть следующим образом:
App.vue
<template>
  <div>
    <Icon name="some-icon-1" />
    <Icon name="some-icon-2" />
    <Icon name="some-icon-3" />
  </div>
</template>

<script lang="ts" setup>
  import Icon from './Icon.vue';
</script>


Тут есть небольшой подводный камень, связанный с размерами (use не учитывает width, height, viewBox иконки, которая в Spritemap). Обходится элементарно - добавлением размера для svg с помощью CSS.

Если вам нужны 2-3 иконки - более рационально будет просто заинлайнить их в template. Не очень оптимизировано, зато не тратим кучи времени на ненужные телодвижения.

В случае с большим количеством иконок (более 500) SVG Sprite будет неэффективен ввиду того, что на каждую страницу будет загружаться тонна ненужных иконок. В таких случаях, лучше хранить иконки без спрайта, просто в ассетах и использовать ссылки на них в <use>.

Ссылки:
- https://developer.mozilla.org/en-US/docs/Web/SVG/E...
Ответ написан
Комментировать
Я в vue не работал, но в react.js лучшим вариантом по производительности считается создание svg спрайта
иконки не входят в компоненты и не увеличивают размер бандла.

Думаю в vue будет лучшим тоже такой способ, вот загуглил и нашел даже библиотеку
https://www.npmjs.com/package/vue-svg-sprite
Ответ написан
Sasha_Odesskiy
@Sasha_Odesskiy
бла-бла-бла!
У меня к примеру папка Icons и в паке IcomName.vue, внутри обычный содержащий svg-иконку. Когда нужна иконка, просто импортирую как обычный компонент Vue.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы