// components/icon/icon.js Component({ properties: { // 图标名称 name: { type: String, value: 'share', observer: 'updateIcon' }, // 图标大小(rpx) size: { type: Number, value: 48 }, // 图标颜色 color: { type: String, value: '#ffffff', observer: 'updateIcon' }, // 自定义类名 customClass: { type: String, value: '' }, // 自定义样式 customStyle: { type: String, value: '' } }, data: { svgData: '', fontGlyph: '' }, lifetimes: { attached() { this.updateIcon() } }, methods: { // iconfont 映射:将业务 name(lucide 风格)映射到 iconfont 的 unicode(形如 "\ue6aa") // 小程序不支持通过 :before { content } 渲染,因此必须直接输出 unicode 字符 getFontGlyph(name) { const map = { // 基础高频(来自 static/iconfont.css 的 content 值) 'wallet': '\ue6c8', 'gift': '\ue6c9', 'user': '\ue6b9', 'search': '\ue6aa', 'share': '\ue6ab', 'home': '\ue694', 'lock': '\ue699', 'camera': '\ue671', 'warning': '\ue6bd', // 箭头/展开 'chevron-left': '\ue6c1', 'chevron-right': '\ue6c6', 'chevron-down': '\ue6c4', 'chevron-up': '\ue6c2', 'arrow-up-right': '\ue6c2', // 交互/状态 'x': '\ue6c3', 'check': '\ue6c7', 'plus': '\ue664', 'trash-2': '\ue66a', 'pencil': '\ue685', 'zap': '\ue75c', 'info': '\ue69c', // 语义近似映射(iconfont 不一定有同名) 'map-pin': '\ue6a8', 'message-circle': '\ue678', 'smartphone': '\ue6a0', 'refresh-cw': '\ue6a4', 'shield': '\ue6ad', 'star': '\ue689', 'heart': '\ue68e', // 其他:若 iconfont 里不存在,则继续走 SVG 兜底 'book-open': '\ue993', 'bar-chart': '\ue672', 'clock': '\ue6b5', } return map[name] || '' }, // SVG 图标数据映射(Lucide 风格,替换原 emoji) getSvgPath(name) { const s = '' const svgMap = { 'share': s + '', 'arrow-up-right': s + '', 'chevron-left': s + '', 'search': s + '', 'heart': s + '', 'user': s + '', 'smartphone': s + '', 'map-pin': s + '', 'home': s + '', 'star': s + '', 'message-circle': s + '', 'package': s + '', 'book-open': s + '', 'lightbulb': s + '', 'handshake': s + '', 'rocket': s + '', 'trophy': s + '', 'refresh-cw': s + '', 'shield': s + '', 'wallet': s + '', 'wrench': s + '', 'camera': s + '', 'phone': s + '', 'clipboard': s + '', 'megaphone': s + '', 'image': s + '', 'gift': s + '', 'lock': s + '', 'lock-open': s + '', 'sparkles': s + '', 'save': s + '', 'globe': s + '', 'users': s + '', 'gamepad': s + '', 'check': s + '', 'trash-2': s + '', 'clock': s + '', 'plus': s + '', 'briefcase': s + '', 'target': s + '', 'rotate-ccw': s + '', 'corner-down-left': s + '', 'folder': s + '', 'bar-chart': s + '', 'link': s + '' } return svgMap[name] || '' }, // 更新图标 updateIcon() { const { name, color } = this.data const fontGlyph = this.getFontGlyph(name) let svgString = this.getSvgPath(name) // 若 iconfont 存在映射,则优先用字体图标;否则走 SVG if (fontGlyph) { this.setData({ fontGlyph, svgData: '' }) return } if (svgString) { // 替换颜色占位符 svgString = svgString.replace(/COLOR/g, color) // 转换为 Base64 Data URL const svgData = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}` this.setData({ svgData: svgData, fontGlyph: '' }) } else { this.setData({ svgData: '', fontGlyph: '' }) } } } })