@winner-fed/plugin-icons-legacy
v1.0.2
Published
适配 WinJS 的 SVG 图标遗留方案插件,专为 Vue2 项目设计,使用 svg-sprite-loader 雪碧图技术。
Readme
@winner-fed/plugin-icons-legacy
适配 WinJS 的 SVG 图标遗留方案插件,专为 Vue2 项目设计,使用 svg-sprite-loader 雪碧图技术。
功能特性
- ✅ SVG 雪碧图方案:使用 svg-sprite-loader 将 SVG 图标转换为 symbol 标签
- ✅ 灵活的优化配置:集成 svgo-loader,支持自定义 SVGO 插件配置
- ✅ 单色/多色模式:支持单色图标(CSS 控制)和多色图标(保留原始颜色)
- ✅ 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'
],
// 可选:SVGO 优化配置
svgoOptions: {
multicolor: false, // 默认单色模式
plugins: [
// 自定义 SVGO 插件配置
]
}
}
});配置选项
| 选项 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| include | string[] | [] | 额外的图标目录路径,默认已包含 src/icons |
| svgoOptions | object | {} | SVGO SVG 优化配置选项 |
| svgoOptions.multicolor | boolean | false | 是否保留多色 SVG,false 为单色模式 |
| svgoOptions.plugins | Array<string \| object> | 默认配置 | 自定义 SVGO 插件配置数组 |
使用方式
1. 目录结构
src/
├── icons/
│ ├── index.js # 图标入口文件
│ └── svg/
│ ├── dog.svg # 图标文件
│ ├── cat.svg
│ └── ...
├── components/
│ └── SvgIcon/
│ └── index.vue # 图标组件
└── pages/
└── index.vue2. 图标入口文件
创建 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];
});3. SvgIcon 组件
创建 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>4. 在页面中使用
<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>5. 全局注册组件
在 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);高级配置
单色模式配置(默认)
单色模式下,SVGO 会自动移除 SVG 的 fill 和 stroke 属性,让图标支持 CSS 颜色控制:
export default defineConfig({
iconsLegacy: {
svgoOptions: {
multicolor: false // 默认值
}
}
});多色模式配置
多色模式下,保留 SVG 的原始颜色,适用于品牌 logo 或复杂的彩色图标:
export default defineConfig({
iconsLegacy: {
svgoOptions: {
multicolor: true // 保留原始颜色
}
}
});自定义 SVGO 插件配置
完全自定义 SVGO 优化规则:
export default defineConfig({
iconsLegacy: {
svgoOptions: {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false, // 保留 viewBox
cleanupIDs: false // 保留 ID
}
}
},
'cleanupListOfValues',
{
name: 'removeAttrs',
params: {
attrs: '(fill|stroke|class)' // 移除指定属性
}
},
'sortAttrs', // 排序属性
{
name: 'addAttributesToSVGElement',
params: {
attributes: [{
'data-icon': 'true' // 添加自定义属性
}]
}
}
]
}
}
});混合配置示例
结合多个配置选项的完整示例:
export default defineConfig({
presets: [require.resolve('@winner-fed/preset-vue2')],
plugins: [require.resolve('@winner-fed/plugin-icons-legacy')],
iconsLegacy: {
// 多目录支持
include: [
'src/icons', // 默认图标目录
'src/assets/svg', // 额外图标目录
'packages/shared/icons' // 共享图标目录
],
// SVGO 配置
svgoOptions: {
multicolor: false, // 单色模式
plugins: [
'preset-default',
'cleanupListOfValues',
{
name: 'removeAttrs',
params: {
attrs: '(fill|stroke)' // 移除颜色属性以支持 CSS 控制
}
}
]
}
}
});高级用法
动态引入图标
// 动态引入特定图标
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:使用可配置的 SVGO 插件优化 SVG 文件
- 单色模式:移除 fill 和 stroke 属性,支持 CSS 控制
- 多色模式:保留原始颜色信息
- 自定义插件:支持完全自定义的优化规则
- 符号引用:通过
<use>标签引用 symbol,实现图标复用 - 自动配置:插件自动配置 Webpack 和 Rsbuild 的加载规则
- 智能默认配置:基于最佳实践提供合理的默认 SVGO 配置
注意事项
- 仅支持 Vue2 项目,需要配合
@winner-fed/preset-vue2使用 - SVG 文件应放在指定的图标目录中(默认
src/icons) - 图标名称基于文件名,使用时需要保持一致
- 单色模式:建议 SVG 文件不要包含 fill 和 stroke 属性,让组件控制颜色
- 多色模式:SVG 文件会保留原始颜色,适用于品牌 logo 或复杂图标
- 自定义 SVGO 配置会覆盖默认优化规则,请确保配置正确
常见问题
Q: 为什么图标不显示?
A: 请确保:
- 正确引入了
@/icons入口文件 - SVG 文件放在正确的目录中
- 图标名称与文件名一致
- 配置了正确的 preset-vue2
Q: 如何自定义图标样式?
A: 通过 CSS 控制:
.svg-icon {
width: 20px;
height: 20px;
fill: #333;
}Q: 如何添加更多图标目录?
A: 在配置中添加 include 选项:
iconsLegacy: {
include: ['src/assets/icons', 'src/shared/icons']
}Q: 如何使用多色图标?
A: 设置 multicolor: true 保留原始颜色:
iconsLegacy: {
svgoOptions: {
multicolor: true
}
}Q: 如何自定义 SVGO 优化规则?
A: 通过 svgoOptions.plugins 配置:
iconsLegacy: {
svgoOptions: {
plugins: [
'preset-default',
{ name: 'removeAttrs', params: { attrs: '(fill|stroke)' } }
]
}
}Q: 单色模式下图标颜色如何控制?
A: 通过 CSS 的 fill 属性:
.svg-icon {
fill: #ff0000; /* 红色 */
}
.svg-icon:hover {
fill: #00ff00; /* 悬停时绿色 */
}许可证
MIT
