vue@2 使用 svg-icon:webpack + svg-sprite-loader
项目结构
$ tree -I node_modules
.
├── README.md
├── package.json
├── pnpm-lock.yaml
├── public
│ ├── index.html
│ └── libs
│ └── vue@2.6.14.min.js
├── src
│ ├── App.vue
│ ├── icons
│ │ ├── SvgIcon.vue
│ │ ├── index.js
│ │ └── svg
│ │ └── open.svg
│ └── main.js
└── webpack.config.js
依赖
npm i svg-sprite-loader svgo-loader -D
webpack 配置
// webpack.config.js
const path = require('path');
module.exports = {
module: {
rules: [
// 处理svg图标
{
test: /\.svg$/,
include: [path.resolve('./src/icons/svg')],
use: [
{
loader: 'svg-sprite-loader',
options: {
symbolId: 'icon-[name]',
},
},
// 移除svg的fill属性
{
loader: 'svgo-loader',
options: {
// 必须指定name!
plugins: [
{
name: 'removeAttrs',
params: { attrs: 'fill' },
},
],
},
},
],
},
],
},
};
定义 Vue 组件
<!-- src/icons/SvgIcon.vue -->
<template>
<svg class="svg-icon" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script>
// svg 组件
export default {
name: 'svg-icon',
props: {
name: {
type: String,
required: true,
},
},
computed: {
iconName() {
return `#icon-${this.name}`;
},
},
};
</script>
<style lang="less">
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
// src/icons/index.js
import SvgIcon from './SvgIcon.vue'; // svg component
// import all svg
const req = require.context('./svg', false, /\.svg$/);
const requireAll = (requireContext) =>
requireContext.keys().map(requireContext);
requireAll(req);
// register globally
export default {
install(Vue) {
Vue.component('svg-icon', SvgIcon);
},
};
全局注册
import Vue from 'vue';
import SvgIcon from './icons/index.js';
Vue.use(SvgIcon);
使用 icon
<svg-icon name="open"></svg-icon>
完整代码:https://github.com/mouday/vue2-svg-demo
在线 demo: https://mouday.github.io/vue2-svg-demo/dist/
参考: