やりたいこと
SVGをVueComponentとして読み込む場合と、ファイルパスとして読み込む場合のどちらにも対応したい。
例えば、アイコンなどは、vue-svg-loaderを使ってVueComponentとして読み込んで、色や塗り、線などをスタイルの変更をしたい。
<template lang="pug">
download-icon.icon
</template>
<script>
import DownloadIcon from '@/assets/images/icons/download.svg'
export default {
components: {
DownloadIcon,
},
}
</script>
<style>
.icon {
fill: #000;
}
</style>
ロゴ画像の場合は、ファイルパスとして読み込んで画像として出力したい。
<template lang="pug">
img(src="@/assets/images/logo.svg")
</template>
しかし、VueCLIのデフォルトの設定やvue-svg-loaderのリファレンスの設定だと、どちらか一方の方法でしか読み込めないので、設定方法を変更する必要がある。
実現方法
oneOfを使うと、一つの条件(今回の場合は、test: /\.svg/
)に対して、どのLoaderを使うかを指定できる。
公式リファレンスでは、cssに対して、hoge.css?inline
と?inline
を付けた場合は、url-loaderで読み込み、hoge.css?file
とした場合は、file-loaderで読み込む設定となっている。
今回紹介するのは、SVGファイルに対して、デフォルトではfile-loaderで読み込み、@/assets/images/icons/download.svg?component
と?component
と付けた場合は、vue-svg-loaderで読み込みVueComponentになるように設定する。
実装
Webpackの設定は以下のようになる。
module.exports = {
//...
module: {
rules: [
{
test: /\.svg$/,
oneOf: [
// VueComponent
{
resourceQuery: /component/,
use: 'vue-svg-loader',
},
// デフォルト
{
use: 'file-loader',
},
],
},
],
},
}
VueCLIを使っている場合
VueCLIの場合は、すでにsvgに対するルールが設定されているので、それを書き換える必要がある。
vue.config.jsに以下の設定を追加する。
module.exports = {
//...
chainWebpack: (config) => {
const svgRule = config.module.rule('svg')
svgRule
.oneOf('component')
.resourceQuery(/component/)
.use('vue-svg-loader')
.loader('vue-svg-loader')
.end()
.end()
svgRule.oneOf('normal').uses.merge(svgRule.uses.entries())
svgRule.uses.clear()
},
}
以上の設定で、VueComponentとして読み込むこともできるし、ファイルパスとして読み込むことができる。
まとめ
以下のように、VueComponentとファイルパスの両方で、SVGを読み込むことができる。
<template lang="pug">
div
download-icon.icon
img(src="@/assets/images/logo.svg")
</template>
<script>
import DownloadIcon from '@/assets/images/icons/download.svg?component'
export default {
components: {
DownloadIcon,
},
}
</script>
<style>
.icon {
fill: #000;
}
</style>