element-plus内置有一些常用的icon供我们使用,但是我们假如需要用自己的icon时候,我们可以搞一个icon自定义组件;
先把icons文件放到src下;
再新建一个SvgIcon组件;
index.vue
<template>
<svg class="svg-icon" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script setup>
import { defineProps, computed } from 'vue'
const props = defineProps({
icon: {
type: String,
required: true
}
})
const iconName = computed(() => {
return `#icon-${props.icon}`
})
</script>
<style lang="scss" scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
icons下新建index.js
import SvgIcon from '@/components/SvgIcon'
const svgRequired = require.context('./svg', false, /\.svg$/)
svgRequired.keys().forEach((item) => svgRequired(item))
// 注册全局组件
export default (app) => {
app.component('svg-icon', SvgIcon)
}
main.js里面导入SvgIcon
import SvgIcon from '@/icons'
createApp(App).use(store).use(router).use(ElementPlus).use(SvgIcon).mount('#app')
安装 svg-sprite-loader
vue.config.js添加:
const webpack = require('webpack');
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
lintOnSave: false,
chainWebpack(config) {
// 设置 svg-sprite-loader
// config 为 webpack 配置对象
// config.module 表示创建一个具名规则,以后用来修改规则
config.module
// 规则
.rule('svg')
// 忽略
.exclude.add(resolve('src/icons'))
// 结束
.end()
// config.module 表示创建一个具名规则,以后用来修改规则
config.module
// 规则
.rule('icons')
// 正则,解析 .svg 格式文件
.test(/\.svg$/)
// 解析的文件
.include.add(resolve('src/icons'))
// 结束
.end()
// 新增了一个解析的loader
.use('svg-sprite-loader')
// 具体的loader
.loader('svg-sprite-loader')
// loader 的配置
.options({
symbolId: 'icon-[name]'
})
// 结束
.end()
config
.plugin('ignore')
.use(
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/)
)
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()
}
}
使用:
<svg-icon icon="password" class="svg-container"></svg-icon>
<svg-icon icon="user" class="svg-container"></svg-icon>