本文へスキップ
SvgJsx
言語: 日本語

SVG を Vue 単一ファイルコンポーネントに変換

任意の SVG を、きれいな <template>、オプションの <script setup lang="ts">、size プロパティを備えた Vue 3 の単一ファイルコンポーネント(.vue)に変換し、そのままアプリにインポートできます。

クイックプリセット:
.svg ファイルをここにドロップ、またはファイルは FileReader でローカルに読み込まれ、アップロードされることはありません。
オプション
エクスポート:
<script setup lang="ts">
defineOptions({ name: "HeartIcon" });
</script>

<template>
  <svg width="24" height="24" viewBox="0 0 24 24" class="icon icon-heart">
    <g id="Layer_1" fill="none" stroke="#e11d48" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="M19.0001 14.0002c1.4900-1.4600 3.0000-3.2100 3.0000-5.5000A5.5000 5.5000 0 0 0 16.5000 3c-1.7600 0-3.0000.5000-4.5000 2-1.5000-1.5000-2.7400-2-4.5000-2A5.5000 5.5000 0 0 0 2 8.5000c0 2.3000 1.5000 4.0500 3 5.5000l7 7Z" style="fill-opacity:0.15;fill:#e11d48" />
    </g>
  </svg>
</template>

プレビュー

変換後の SVG のプレビュー
元の SVG
706B
最適化後の SVG
538B(-24%)
コンポーネント
580B

Vue 向け出力の内容

Vue テンプレートは SVG 属性をそのまま受け付けるため、stroke-width や class などのケバブケースの名前は維持されます。エディタ由来の不要な情報と XML 宣言を取り除き、必要に応じて xmlns も削除したうえで、マークアップを <template> ブロックに配置します。

size オプションを有効にすると、デフォルト値付きの size プロパティを宣言する <script setup> ブロックが追加され、:width と :height にバインドされます。TypeScript の場合は defineProps<{ size?: number | string }>() と withDefaults で宣言します。

属性のフォールスルー

<svg> が唯一のルート要素なので、props として宣言されていない属性は Vue が自動的に転送します。つまり class、style、aria-label、@click などのイベントリスナーは、追加のコードなしで <svg> に適用されます。そのため Vue では props 展開オプションは不要です。

コンポーネントの使い方

Vue 3 や Nuxt プロジェクトでの典型的な使い方:

  • 出力を components フォルダに IconName.vue として保存します。
  • インポートします:import IconName from "./IconName.vue"。
  • 任意のテンプレートで <IconName :size="20" class="text-emerald-600" /> と描画します。
  • currentColor を有効にすると、アイコンは CSS の color プロパティに従います。

よくある質問

出力は Vue 2 でも動きますか?

テンプレート部分は Vue 2.7 でも動作しますが、defineProps を使う <script setup> には Vue 2.7 または Vue 3 が必要です。それより古い Vue 2 のプロジェクトでは size プロパティをオフにして、テンプレートのみのコンポーネントを生成してください。

Nuxt で使えますか?

はい。ファイルを components ディレクトリに置けば、Nuxt が名前で自動インポートします。たとえば components/IconArrow.vue は <IconArrow /> として使えます。

SVG 内の <style> について Vue が警告を出すのはなぜ?

<style> タグには副作用があるため、Vue はテンプレートからそれを取り除きます。CSS はコンポーネントの <style scoped> ブロックに移すか、変換前に属性へ書き換えてください。

vite-svg-loader のほうがよいのでしょうか?

ビルド時に大量の SVG をインポートするならローダーが便利です。.vue ファイルに変換すれば、マークアップと props を完全に管理でき、ビルド設定も不要です。