通用svg图标组件——SvgIcon
实现一个通用的svg图标组件
1.可以使用项目内部的svg图标
2.也可以使用外部传入的svg图标
SvgIcon.vue:
<template>
<!-- 显示外部传入的svg -->
<div
v-if="isExternal"
:style="styleExternalIcon"
class="svg-external-icon svg-icon"
:class="className"
/>
<!-- 显示项目内部的svg -->
<svg v-else class="svg-icon" :class="className" aria-hidden="true">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
import { isExternal } from '../utlis/validate'
export default {
name: 'SvgIcon',
props: {
// icon 图标
icon: {
type: String,
required: true
},
// 图标类名
className: {
type: String,
default: ''
}
},
computed: {
/**
* 判断是否为外部图标
*/
isExternal() {
return isExternal(this.icon)
},
/**
* 外部图标样式
*/
styleExternalIcon() {
return {
mask: `url(${this.icon}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.icon}) no-repeat 50% 50%`
}
},
/**
* 项目内图标
*/
iconName() {
return `#icon-${this.icon}`
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
/* 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */
vertical-align: -0.15em;
/* fill 是SVG元素的一种属性;SVG元素的这些属性,用于指定如何处理或者呈现元素的详细信息
比如,fill ,对于形状元素和文本,它定义了绘制元素的颜色。对于动画,它定义了动画的最终状态。在下面的例子中,它定义了图标的颜色。
在css中,currentColor是一个变量,这个变量的值是当前元素的color值。
如果当前元素没有在CSS里显示地指定一个color值,那它的颜色值就遵从CSS规则,从父元素继承而来。 */
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
}
</style>
validate.js:
/**
* 判断是否为外部资源
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
批量引入svg并且注册svg-icon组件
@/icons/index.js:
import SvgIcon from '../components/SvgIcon.vue'
// 批量引入项目内的.svg文件
const svgRequire = require.context('./svg', false, /.svg$/)
svgRequire.keys().forEach(svgIcon => svgRequire(svgIcon))
// 全局注册 SvgIcon 组件
export default app => {
app.component('svg-icon', SvgIcon)
}
在mani.js中安装svg-icon组件为全局组件
main.js:
import installIcons from './icons/index
installIcons(app)
安装svg-loader让svg得以显示
安装:
npm i --save-dev svg-sprite-loader@6.0.9
在vue.config.js中对svg进行修改
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
// https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F
module.exports = {
chainWebpack(config) {
// 设置 svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通