前面文章有講到 svg 圖標按需加載的優勢以及 Vue 如何使用 vue-svg-icon 實現 svg 圖標按需載入
今天來學習一下使用 svg-sprite-loader 在 Vue3 項目中實現圖標按需加載
1、將 email.svg 文件導入項目
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 4H20C21.1 4 22 4.9 22 6V18C22 19.1 21.1 20 20 20H4C2.9 20 2 19.1 2 18V6C2 4.9 2.9 4 4 4Z" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
<path d="M22 6L12 13L2 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
這里將 svg 圖標中對應的圖標顏色值改為字符串 currentColor,方便使用時控制圖標實時顏色
將圖標放在特定文件夾下,這里以 @/assets/svg 中導入的 svg 為例
2、安裝 svg-sprite-loader
npm i svg-sprite-loader
3、配置 vue.config.js
module.exports = {
// 配置使用stylus全局變量
chainWebpack: config => {
const svgRule = config.module.rule("svg");
svgRule.uses.clear();
svgRule
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]"
})
.end();
}
};
4、新建 SvgIcon.vue 文件,這里可傳入 name 屬性控制圖標類型,傳入 size 屬性控制圖標大小,傳入 color 屬性控制圖標顏色
這里以 composition API 的寫法為例:
<template>
<svg
class="svg-icon"
:style="{
width: props.size + 'px',
height: props.size + 'px',
color: props.color
}"
@mousedown="clickIcon"
>
<use :xlink:href="`#icon-${props.name}`" :fill="props.color" />
</svg>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "SvgIcon",
props: {
name: {
type: String,
required: true,
default: "email"
},
size: {
type: Number,
default: 32
},
color: {
type: String,
default: "#000"
}
},
setup(props) {
return {
props
};
}
});
</script>
5、在 src 目錄下新建 plugin.ts
import SvgIcon from "@/pages/components/SvgIcon.vue";
const componentPlugin: any = {
install: function(vue: any, options: any) {
if (
options &&
options.imports &&
Array.isArray(options.imports) &&
options.imports.length > 0
) {
// 按需引入圖標
const { imports } = options;
imports.forEach((name: any) => {
require(`@/assets/svg/${name}.svg`);
});
} else {
// 全量引入圖標
const ctx = require.context("@/assets/svg", false, /\.svg$/);
ctx.keys().forEach(path => {
const temp = path.match(/\.\/([A-Za-z0-9\-_]+)\.svg$/);
if (!temp) return;
const name = temp[1];
require(`@/assets/svg/${name}.svg`);
});
}
vue.component(SvgIcon.name, SvgIcon);
}
};
export default componentPlugin;
6、在 main.js(或 main.ts)中引入上面的 plugin 文件
Vue2:
import plugin from "./plugin";
Vue.use(plugin, {imports: []})
Vue3:
import plugin from "./plugin";
createApp(App)
.use(plugin, {
imports: []
})
7、圖標組件的使用
<SvgIcon name="email" :size="24" color="#777" />