适配 WinJS 的 SVG 图标遗留方案插件,专为 Vue2 项目设计,使用 svg-sprite-loader 雪碧图技术。
- ✅ SVG 雪碧图方案:使用 svg-sprite-loader 将 SVG 图标转换为 symbol 标签
- ✅ 自动优化:集成 svgo-loader 自动优化 SVG 文件,移除填充和描边属性
- ✅ Vue2 专用:专门为 Vue2 项目优化,配合 @winner-fed/preset-vue2 使用
- ✅ 自定义路径:支持配置多个图标目录路径
- ✅ 开箱即用:默认处理
src/icons
目录下的 SVG 文件 - ✅ Webpack 兼容:同时支持 Webpack 和 Rsbuild 构建方式
npm install @winner-fed/plugin-icons-legacy -D # 或 yarn add @winner-fed/plugin-icons-legacy -D # 或 pnpm add @winner-fed/plugin-icons-legacy -D
在 .winrc.ts
文件中配置:
import { defineConfig } from 'win'; export default defineConfig({ presets: [require.resolve('@winner-fed/preset-vue2')], plugins: [require.resolve('@winner-fed/plugin-icons-legacy')], iconsLegacy: { // 可选:自定义图标目录 include: [ 'src/assets/icons', 'src/components/icons' ] } });
选项 | 类型 | 默认值 | 描述 |
---|---|---|---|
include |
string[] |
[] |
额外的图标目录路径,默认已包含 src/icons |
src/
├── icons/
│ ├── index.js # 图标入口文件
│ └── svg/
│ ├── dog.svg # 图标文件
│ ├── cat.svg
│ └── ...
├── components/
│ └── SvgIcon/
│ └── index.vue # 图标组件
└── pages/
└── index.vue
创建 src/icons/index.js
:
const req = require.context('./svg', false, /\.svg$/); const requireAll = (requireContext) => requireContext.keys(); // 自动引入所有 SVG 图标 requireAll(req).map(req); const re = /\.\/(.*)\.svg/; // 导出图标名称列表(可选) export const iconNames = requireAll(req).map((i) => { return i.match(re)[1]; });
创建 src/components/SvgIcon/index.vue
:
<template> <svg :class="['svg-icon', className]" aria-hidden="true" @click="clickHandle"> <use :xlink:href="'#icon-' + (iconName || name)" /> </svg> </template> <script> export default { name: 'SvgIcon', props: { iconName: { type: String, required: false }, name: { type: String, required: false }, className: { type: [String, Array], default: '' } }, mounted() { if (!this.name && !this.iconName) { console.error('Missing required prop: "iconName or name"'); } }, methods: { clickHandle() { this.$emit('click'); } } }; </script> <style scoped> .svg-icon { width: 1em; height: 1em; fill: currentColor; vertical-align: -0.15em; overflow: visible; position: relative; } </style>
<template> <div> <!-- 使用 name 属性 --> <svg-icon name="dog" class="icon-large"></svg-icon> <!-- 使用 iconName 属性 --> <svg-icon iconName="cat" @click="handleIconClick"></svg-icon> <!-- 自定义样式 --> <svg-icon name="star" :className="['icon-star', 'active']"></svg-icon> </div> </template> <script> // 引入图标 import '@/icons'; export default { methods: { handleIconClick() { console.log('图标被点击了'); } } }; </script> <style> .icon-large { font-size: 24px; color: #1890ff; } .icon-star.active { color: #faad14; } </style>
在 main.js
中全局注册:
import Vue from 'vue'; import SvgIcon from '@/components/SvgIcon'; // 引入图标 import '@/icons'; // 全局注册组件 Vue.component('svg-icon', SvgIcon); // 或者使用插件方式 const iconPlugin = { install(Vue) { Vue.component('svg-icon', SvgIcon); } }; Vue.use(iconPlugin);
// 动态引入特定图标 const importIcon = (name) => { return import(`@/icons/svg/${name}.svg`); }; // 批量引入 const importIcons = (names) => { return Promise.all(names.map(name => importIcon(name))); };
// 获取所有可用图标名称 import { iconNames } from '@/icons'; export default { data() { return { availableIcons: iconNames }; } };
- svg-sprite-loader:将 SVG 文件转换为
<symbol>
标签,并生成雪碧图 - svgo-loader:优化 SVG 文件,移除不必要的属性(如 fill、stroke)
- 符号引用:通过
<use>
标签引用 symbol,实现图标复用 - 自动配置:插件自动配置 Webpack 和 Rsbuild 的加载规则
- 仅支持 Vue2 项目,需要配合
@winner-fed/preset-vue2
使用 - SVG 文件应放在指定的图标目录中(默认
src/icons
) - 图标名称基于文件名,使用时需要保持一致
- 建议 SVG 文件不要包含 fill 和 stroke 属性,让组件控制颜色
A: 请确保:
- 正确引入了
@/icons
入口文件 - SVG 文件放在正确的目录中
- 图标名称与文件名一致
- 配置了正确的 preset-vue2
A: 通过 CSS 控制:
.svg-icon { width: 20px; height: 20px; fill: #333; }
A: 在配置中添加 include
选项:
iconsLegacy: { include: ['src/assets/icons', 'src/shared/icons'] }
MIT.