じまろぐ

めめ

Vueでsvgファイルをいい感じに扱う

svgtemplateにコピペする暗黒時代の終わりを告げる

vue-svg-loader を使う

github.com

vue-svg-loaderを使うとsvgファイルをvueコンポーネントとして扱えるようになる

<template>
    <a href="https://github.com/vuejs/vue">
      <VueLogo />
      Vue
    </a>
</template>
<script>
import VueLogo from './public/vue.svg';

export default {
  name: 'Example',
  components: {
    VueLogo,
  },
};
</script>

Nuxtで使うときは nuxt.config.jsbuild.extend でloaderを設定

ドキュメント: https://github.com/visualfanatic/vue-svg-loader/#basic-configuration

export default {
  build: {
    extend(config) {
      const svgRule = config.module.rules.find(rule => rule.test.test('.svg'));
      svgRule.test = /\.(png|jpe?g|gif|webp)$/i

      config.module.rules.push({
        test: /\.svg$/,
        loader: 'vue-svg-loader',
      })
    },
  },
}

これでsvgファイルをコンポーネントとして好きに使える

動的なパス指定でsvgを読み込むコンポーネントを作る

svgの数だけ import して components に登録するのもめんどうなのでsvg読み込むvueコンポーネントを作る

<template>
  <component :is="svg"/>
</template>

<script>
export default {
  name: "SVGElement",
  props: {
    name: {
      type: String,
    },
  },
  computed: {
    svg() {
      return () => import(`~/assets/img/${this.name}.svg`)
    }
  }
}
</script>

この例だと src/assets/img/ の中から name で指定したファイル名のsvgを読み込める。 ~/assets/img/${this.name}.svg の部分は自分の環境と使い方に合わせてお好きなように

使う側はこんな感じ

<template>
  <div>
    <SVGElement name="bars"/>
  </div>
<template>

<script>
import SVGElement from "~/elements/SVGElement"
export default {
  name: "ProjectsPage",
  components: { SVGElement },
}
</script>

これがVueでsvgを扱う体験の一番いいやつ、と思う