我觉得拿自己以前发过的文章应该是不能叫做抄吧!
我之前在iconfont图标库找到了一些比较精美的图标,但是当我兴高采烈的拿着从阿里妈妈图标库去用的时候发现,颜色是黑的,emmmm…,当然颜色是可以修改的,但是有些图标改完后就不是原来的图标了,她已经不是原来的那个她了,哈哈哈哈,接下里,带你从0来封装一个可服用的svg组件。虽然好用但是也不要用太多,可能会导致页面卡顿。
下面正片开始:
首先你需要安装一个插件
npm i svg-sprite-loader -D
然后在vue-config,js当中配置如下:
const { defineConfig } = require("@vue/cli-service");
const path = require("path");
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
chainWebpack: (config) => {
config.module.rules.delete("svg"); // 重点:删除默认配置中处理svg
config.module
.rule("svg-sprite-loader") // rule 匹配规则
.test(/\.svg$/) // 用正则匹配 文件
.include // 包含
.add(resolve("src/icon")) // 处理svg目录
.end()
.use("svg-sprite-loader") // 配置loader use() 使用哪个loader
.loader("svg-sprite-loader") // 加载loader
.options({
// [name] 变量。一般表示匹配到的文件名 xxx.svg
// 注意: symbolId 在
symbolId: "dl-icon-[name]", // 将所有的.svg 集成到 symbol中,当使用 类名 icon-文件名
});
},
});
接下来在src当中创建新文件夹icons,然后在该文件夹下创建index.js,内容如下:
// 这里是 ./svg是路径
const webpackContext = require.context("./svg", false, /\.svg$/);
const requireAll = (requireContext) => {
// requireContext.keys() 匹配的 文件路径数组
return requireContext.keys().map(requireContext);
};
// 得到一个完整解析的module数组
requireAll(webpackContext);
接着在icons下创建文件夹svg,与上面相对应。如果你与我配置的路径不对也是需要修改vue.config.js当中的配置的。在svg文件夹下是你想要使用的 XXX.svg,名字根据自己爱好命名即可。
目录结构如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZMycUZPq-1665467594713)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5128f4ab48424d3d805de9c9de5431da~tplv-k3u1fbpfcp-watermark.image?)]
接下来就是封装svg组件了,在components目录下创建ScgIcon.vue文件,文件代码如下:
<template>
<svg
:class="svgClass"
aria-hidden="true"
:style="
props.width
? `width:${props.width}px;height:${props.width}px;${
props.cursor ? 'cursor:pointer;' : ''
}`
: ''
"
>
<use :xlink:href="iconName" />
svg>
template>
<script>
import { computed } from "@vue/reactivity";
export default {
props: {
iconClass: {
type: String,
required: true,
},
className: {
type: String,
default: "",
},
width: {
type: Number,
default: 0,
},
cursor: {
type: Boolean,
default: true,
},
},
setup(props) {
// 图标在 iconfont 中的名字
const iconName = computed(() => {
return `#dl-icon-${props.iconClass}`;
});
// 给图标添加上类名
const svgClass = computed(() => {
if (props.className) {
return `svg-icon ${props.className}`;
}
return "svg-icon";
});
return {
svgClass,
iconName,
props,
};
},
};
script>
<style lang="less" scoped>
.svg-icon {
width: 30px;
height: 30px;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
transition: all 1s;
}
.big-svg-icon {
width: 50px;
height: 50px;
}
style>
这里我对组件封装并且传入了一些参数,当然你也可以在此基础上对我封装的代码进行修改,参数名词解释如下:
iconClass
: 这个就是 XXX.svg的 XXX内容
className
: 这个是一个类名根据你传入的类名去使用下面style标签当中的样式,因为我觉得这个并不是很好用,所以对此进行了一些修改
width
: 这个就是对传进来的width进行一个动态赋值,因为如果使用类名显得过于臃肿30px,40px,50px等等会需要写很多的类名,并不能按照我的要求随心所欲的去改变大小所以进行了这样的修改
cursor
: 鼠标移动是否显示小手,通过true和false来控制,true就是cursor:pointer; false并不会显示小手
不要着急马上就结束了,接下来就是在Vue当中全局注册这个组件,全局使用肯定是要香一点。然后就是在main.js
当中去全局注册这个组件。代码如下:
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import "@/icons/index"; // 将src/icons/index.js引入
import SvgIcon from "./components/SvgIcon.vue"; // 引入SvgIcon.vue
// 在这里注册.component("svg-icon", SvgIcon)注意不要放在mount后面,要放在前面
createApp(App).use(router).component("svg-icon", SvgIcon).mount("#app");
接下来你就可以尽情的使用这个组件了。
<template>
<div
class="route"
v-for="item in content"
:key="item.id"
@click="toBlog(item)"
>
<svg-icon :iconClass="item.iconClass" :width="item.width">svg-icon>
<div v-if="item.title">{{ item.title }}div>
div>
template>
<script setup>
const content = [
{ id: 1, iconClass: "home", width: "30", path: "/" },
{ id: 2, iconClass: "wenzhang", width: "30", path: "/blog" },
{ id: 3, iconClass: "ziliao", width: "30" },
]
script>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-We00HV8g-1665467594714)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b5bb127f65884d94aa99219d1f50dc29~tplv-k3u1fbpfcp-watermark.image?)]