资源引入式组件的方式使用
pnpm install vite-svg-loader --save-dev
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import svgLoader from "vite-svg-loader";
export default defineConfig({
plugins: [
vue(),
svgLoader()
]
}
页面使用
<template>
<div>
<Cake />
</div>
</template>
<script setup>
import Cake from "@assets/svg/cake.svg";
</script>
效果:
svg雪碧图-组件式直接引入
资源引入的弊端:
在上面第一种svg的使用方式中,svg是以资源引入的方式使用的,那就意味每使用一个svg就要import一次,在vite中,import算是一个http请求,如果页面使用多个svg,那么就要引入多次,比较消耗性能,如下:
import Cake1 from "@assets/svg/cake1.svg";
import Cake2 from "@assets/svg/cake2.svg";
import Cake3 from "@assets/svg/cake3.svg";
import Cake4 from "@assets/svg/cake4.svg";
如果页面中有100个svg,那么就要发送100个http请求,相当麻烦。
解决方法:
所以我们可以将svg以文件夹的形式生成雪碧图,这样我们就能直接使用该文件夹下的所有svg了。
pnpm i vite-plugin-svg-icons -D
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import path from 'path'; // ts如果报错 pnpm i @types/node -D
export default () => {
return {
plugins: [
createSvgIconsPlugin({
// 配置src下存放svg的路径,这里表示在src/icons文件夹下
iconDirs: [path.resolve(process.cwd(), 'src/icons')],
symbolId: 'icon-[dir]-[name]',
}),
],
};
};
创建svg组件
<template>
<svg
aria-hidden="true"
:class="svgClass"
:style="{
color: color,
fill: color,
width: iconSize,
height: iconSize
}"
v-bind="$attrs"
>
<use :xlink:href="iconName" :fill="color" />
</svg>
</template>
<script lang="ts" setup>
import { computed } from "vue";
defineOptions({ name: "SvgIcon" });
const props = defineProps({
name: {
type: String,
default: ""
},
color: {
type: String,
default: ""
},
size: {
type: [Number, String],
default: 15
}
});
// 判断传入的值,是否带有单位,如果没有,就默认用px单位
const getUnitValue = (value: string | number): string | number => {
return /(px|em|rem|%)$/.test(value.toString()) ? value : value + "px";
};
// svg大小
const iconSize = computed<string | number>(() => {
return getUnitValue(props.size);
});
// svg名称-对应资源文件夹的svg名称
const iconName = computed<string>(() => `#icon-${props.name}`);
// svg动态类名
const svgClass = computed<string>(() => {
if (props.name) return `svg-icon icon-${props.name}`;
return "svg-icon";
});
</script>
<style lang="scss" scope>
.svg-icon {
width: auto;
height: auto;
vertical-align: middle;
flex-shrink: 0;
}
</style>
在main.ts中使用依赖
import "virtual:svg-icons-register";
import SvgIcon from "./components/SvgIcon/index.vue"; // 全局svg图标组件
const app = createApp(App);
app.component("SvgIcon", SvgIcon); // 全局组件挂载
app.mount("#app");
在页面使用,通过名称指向配置路径下的资源文件
<template>
<div>
<SvgIcon :name="'snow'" :size="20"/>
</div>
</template>
<script setup lang="ts"></script>
<style lang="scss" scoped></style>
页面效果
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。