在开发项目的时候经常会用到svg矢量图,而且我们使用SVG以后,页面上加载的不再是图片资源,
这对页面性能来说是个很大的提升,而且我们SVG文件比img要小的很多,放在项目中几乎不占用资源。
1、安装依赖插件
pnpm install vite-plugin-svg-icons -D
2、配置
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
export default () => {
return {
plugins: [
createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
symbolId: 'icon-[dir]-[name]',
}),
],
}
}
3、main.js/ts导入
import "virtual:svg-icons-register"; //svg插件所需配置代码
4、使用,例如:
在src/assets文件下,创建icons文件
例如复制阿里图标库,svg代码,粘贴
使用:
<!-- svg:图标外层容器节点,内部需要与use标签结合使用 -->
<svg>
<!-- xlink:href执行用哪一个图标,属性值务必#icon-图标名字 -->
<!-- use标签fill属性可以设置图标的颜色·-->
<use xlink:href="#icon-fu" fill="red"></use>
</svg>
效果:
如果要修改图标大小,在svg标签上,直接修改
style="width: 100px, height: 100px"
如果项目中,很多地方都需要用到图标,可以封装成一个公共组件来使用
例如:
1、在src/components目录下创建一个SvgIcon组件
代码:
<template>
<div>
<svg :style="{ width, height }">
<use :xlink:href="prefix + name" :fill="color"></use>
</svg>
</div>
</template>
<script setup lang="ts">
//接受父组件传过来的参数
defineProps({
//xlink:href属性值的前缀
prefix: {
type: String,
default: "#icon-",
},
name: String,
color: {
type: String,
default: "",
},
width: {
type: String,
default: "16px",
},
height: {
type: String,
default: "16px",
},
});
</script>
<style scoped></style>
使用:传入需要的参数,名字、颜色、尺寸
<template>
<div class="box">
<h1>Hello! xu</h1>
<SvgIcon name="fu" color="red" width="200px" height="200px"></SvgIcon>
</div>
</template>
<script setup lang="ts">
import SvgIcon from "@/components/SvgIcon/index.vue";
</script>
<style scoped lang="scss"></style>
效果:
另外,如果全局使用的地方很多,可以注册成一个全局组件来使用,这样就避免每个使用的页面都引用一遍这个SvgIcon组件
例如:在main.ts中引入
import SvgIcon from "@/components/SvgIcon/index.vue"; //全局引入svg图标组件
app.component("SvgIcon", SvgIcon); //全局注册svg图标组件
再者,如果全局公共组件很多,全局注册需要注册很多次组件,可以优化为写一个自定义插件,将全局所有的公共组件注册为全局组件
例如:全局还有一个公共分页器组件叫Pagination
利用自定义插件把这些组件变成全局组件,在components文件夹下,创建index.ts文件,在全局mian.ts,引入自定义插件对象
//引入自定义插件对象,用来注册整个项目的全局组件
import gloalComponent from "@/components/index";
app.use(gloalComponent); //安装自定义插件
index.ts代码
import SvgIcon from "./SvgIcon/index.vue";
import Pagination from "./Pagination/index.vue";
const allGloalComponent: any = { SvgIcon, Pagination };
//暴露插件对象
export default {
//必须叫install
install(app: any) {
Object.keys(allGloalComponent).forEach((key) => {
app.component(key, allGloalComponent[key]); //注册为全局组件
});
},
};
使用:
<template>
<div class="box">
<h1>Hello! xu</h1>
<SvgIcon name="fu" color="red" width="200px" height="200px"></SvgIcon>
<Pagination></Pagination>
</div>
</template>
<script setup lang="ts"></script>
<style scoped lang="scss"></style>
效果: