🧩

SVGアイコンをVueコンポーネントに自動変換する【Nuxt3】

2023/07/09に公開

はじめに

今回は SVG アイコンを手軽に Vue コンポーネントに変換する方法を紹介します。

私の開発現場ではデザイナーさんがデザインした SVG アイコンを使用するケースが多く、アイコンライブラリを使用できない場面があります。これまでは、一つ一つ手動で Vue のコンポーネントに変換していたのですが、それらのコストを下げられないか?と思い、今回の方法にたどり着きました。

似たような環境で楽に SVG アイコンを管理したいとお考えの方の参考になれば幸いです!

はじめにちょっとだけ結論を

unplugin-icons というライブラリを使用して、SVG アイコンをコンポーネントに自動変換します。さまざまなビルドツール・フレームワークに対応しているので、ほとんどの環境で使用できると思います。

前提

開発環境

今回は以下の環境で検証しています。

パッケージ バージョン
nuxt 3.6.2
unplugin-icons 0.16.3

使用する SVG アイコン

Iconify で提供されている mdi:account アイコンを拝借します。

https://icon-sets.iconify.design/mdi/account/

assets/icons/account.svg
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
  <path fill="currentColor" d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4Z"/>
</svg>

これまでの実装方法

今までは基本的に ベースコンポーネントの IconBase.vue と 各アイコンコンポーネント Icon*.vue (今回で言うと IconAccount.vue )を作成していました。

参考:https://v2.ja.vuejs.org/v2/cookbook/editable-svg-icons

https://github.com/sdras/vue-sample-svg-icons/blob/master/src/components/IconBase.vue

components/IconAccount.vue
<template>
  <path fill="currentColor" d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4Z"/>
</template>

数が少なければ大したことはないのですが、SVG アイコンのコードを Vue コンポーネントの形式に合わせて変換するのが地味に面倒でした(単純作業が苦手というのもあります・・・笑)。

【本題】今回の実装方法

unplugin-icons というライブラリを使用します。

このライブラリ自体は Iconify をデータソースとしたアイコンコンポーネントを提供してくれるものですが、バージョン v0.11 からカスタムアイコンにも対応されました。

今回はこのカスタムアイコンに対応した機能を使用して、SVG アイコンをコンポーネントに変換します。

SVG アイコンを準備

Iconify から拝借した SVG アイコンを account.svg という名前で assets/icons に配置します。

.
├── assets
│   └── icons
│       └── account.svg
├── README.md
├── app.vue
├── nuxt.config.ts
├── package.json
├── tsconfig.json
└── yarn.lock

unplugin-icons をインストール

yarn add -D unplugin-icons

nuxt.config.ts に設定を追加

nuxt.config.ts
import { FileSystemIconLoader } from "unplugin-icons/loaders";

export default defineNuxtConfig({
  modules: [
    [
      "unplugin-icons/nuxt",
      {
        customCollections: {
          // NOTE: key がアイコンのコレクション名になるので `icons` のところは任意の名前でOK
          icons: FileSystemIconLoader("./assets/icons"),
        },
      },
    ],
  ],
});

SVG アイコンコンポーネントを使用してみる

アイコンは以下の形式でインポートできます。

import Icon from "~icons/[アイコンのコレクション名]/[アイコン名]";

app.vue で実際に使用してみると以下のような感じになります。

app.vue
<template>
  <div>
    <p>Original</p>
    <IconAccount />

    <p>Size</p>
    <IconAccount width="48" height="48" />
    <IconAccount width="72" height="72" />
    <IconAccount width="96" height="96" />

    <p>Color</p>
    <IconAccount color="red" />
    <IconAccount color="green" />
    <IconAccount color="blue" />
  </div>
</template>

<script setup>
import IconAccount from "~icons/icons/account";
</script>

アイコンコンポーネントのプレビュー

アイコン使用時に指定したいプロパティはサイズと色であることが大半なので、十分に対応できていると思います。

おわりに

SVG アイコンをコンポーネントに自動変換する方法を紹介しました。

手動でコンポーネントを作成するよりも楽になるので、今後はこちらの方法で実装していこうと思います ✨

Discussion