辛酸
今天在用阿里巴巴svg图标时,发现过程很是繁琐,就想封装个简单的组件使用,然鹅,百度搜索出来的结果大多讲的不全,或者是基于vite,导致本小白埋头半天都失败了,现记录一下成功封装方法。
开搞
- 首先安装svg-sprite-loader和file-loader
npm install svg-sprite-loader file-loader -D
- 修改vue.config.js
const path = require('path')
const resolve = dir => path.join(__dirname, dir)
module.exports = defineConfig({
transpileDependencies: true,
chainWebpack: (config) => {
config.module.rule('svg').exclude.add(resolve('src/assets/svg')).end()
config.module.rule('icons').test(/\.svg$/).include.add(resolve('src/assets/svg')).end().use('svg-sprite-loader').loader('svg-sprite-loader').options({
symbolId: 'icon-[name]'
}).end()
config.plugin('define').tap((definitions) => {
Object.assign(definitions[0], {
__VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: 'false',
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false'
})
return definitions
})
}
})
- 在assets目录下创建svg目录,下载的svg图标文件放于此处,如果有报错可仿下方示例进行修改,只保留如下内容即可
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M512 512c-119.466667 0-213.333333-93.866667-213.333333-213.333333s93.866667-213.333333 213.333333-213.333334 213.333333 93.866667 213.333333 213.333334-93.866667 213.333333-213.333333 213.333333z m0-341.333333c-72.533333 0-128 55.466667-128 128s55.466667 128 128 128 128-55.466667 128-128-55.466667-128-128-128zM768 938.666667c-25.6 0-42.666667-17.066667-42.666667-42.666667v-85.333333c0-72.533333-55.466667-128-128-128h-170.666666c-72.533333 0-128 55.466667-128 128v85.333333c0 25.6-17.066667 42.666667-42.666667 42.666667s-42.666667-17.066667-42.666667-42.666667v-85.333333c0-119.466667 93.866667-213.333333 213.333334-213.333334h170.666666c119.466667 0 213.333333 93.866667 213.333334 213.333334v85.333333c0 25.6-17.066667 42.666667-42.666667 42.666667z"></path></svg>
- 在component目录下新建SvgIcon.vue,代码如下:
<template>
<svg :class="svgClass" :style="{ width: size + 'px', height: size + 'px', color: color }" aria-hidden="true">
<use :xlink:href="`#icon-${name}`"/>
</svg>
</template>
<script>
export default {
name: 'SvgIcon',
props: {
name: {
type: String,
required: true
}, // svg 图标名称
className: {
type: String,
default: ''
}, // 指定的类样式
size: {
type: Number,
default: 32
}, // 图标尺寸
color: {
type: String,
default: '#000'
} // 图标颜色
},
created() {
import(`@/assets/svg/${ this.name }.svg`)
},
computed: {
svgClass() {
if(this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
- 修改main.js:
import { createApp } from 'vue'
import App from './App.vue'
// 导入 SvgIcon 组件,可以直接使用阿里巴巴下载svg图标
import SvgIcon from '@/components/SvgIcon'
const M_APP = createApp(App)
// 将 SvgIcon 组件注册为全局组件
M_APP.component('svg-icon', SvgIcon)
M_APP.use(ElementPlus).mount('#app')
- 使用
<template>
<el-select v-model='user.name' placeholder='用户名' type='text' class='input-ctl'>
<template #prefix><svg-icon name='user' :size='18' color='#a8abb2' /></template>
<el-option v-for="item in users" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</template>