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/
参考:
【vue】webpack 插件 svg-sprite-loader—实现自己的 icon 组件
手摸手,带你优雅的使用 icon
使用 svg-sprite-loader、svgo-loader 优化 svg symbols