以下の記事の使い方ですが、
https://qiita.com/shiba_mitue/items/460652ccbb625c42bac1
<icon name="alert" />
よくあるアイコンタグですが、アプリ上数個しか使わないのにWebFontで読み込んだりIconMoonで管理したりがちょっと面倒なので、svgをフォルダに入れればOKなコンポーネントを用意します。
icon.vue
<script setup lang="ts">
import { defineAsyncComponent, h } from 'vue';
interface Props {
name: string // svgfile名と同じにする
size?: number // 大きさはwithDefaultsでいれるので、任意
}
const props = withDefaults(defineProps<Props>(), {
name: '',
size: 32
});
const icon = defineAsyncComponent(async () => {
return await import(`./icons/${props.name}.svg`).then(() => {
return import(`./icons/${props.name}.svg`);
}).catch(e => {
console.warn(e);
return h('div', props.name); // SVGが無い場合はdevでnamaを表示
});
});
</script>
<template>
<component
:is="icon"
v-bind="$attrs"
class="m-icon"
:height="size"
:name="name"
:width="size"
/>
</template>
<style scoped>
.m-icon {
display: block;
fill: var(--color-text);
}
</style>
前提として、SVGローダー導入済み、.vuefileと同位置にiconsフォルダを用意している状態。
※vue3+vite環境なのでvite用のSVGローダーを入れています。
┝ composables
┝ icon.vue
┝ icons
┝ alert.svg
yarn add -D vite-svg-loader
vite.config.ts
import svgLoader from 'vite-svg-loader';
export default defineConfig({
plugins: [
svgLoader()
],
})