// 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 映射:与 static/iconfont.wxss 一一对应(icon-xxx -> xxx)
// 小程序不支持通过 :before { content } 渲染,因此必须直接输出 unicode 字符
getFontGlyph(name) {
const map = {
// === 来自 iconfont.wxss 完整映射 ===
'qianbao': '\ue6c8',
'gift': '\ue6c9',
'zap1': '\ue75c',
'user': '\ue6b9',
'upload': '\ue6ba',
'work': '\ue6bb',
'training': '\ue6bc',
'warning': '\ue6bd',
'zoom-in': '\ue6be',
'zoom-out': '\ue6bf',
'arrow-left-bold': '\ue6c1',
'arrow-up-bold': '\ue6c2',
'close-bold': '\ue6c3',
'arrow-down-bold': '\ue6c4',
'minus-bold': '\ue6c5',
'arrow-right-bold': '\ue6c6',
'select-bold': '\ue6c7',
'money-wallet': '\ue833',
'book-open': '\ue993',
'biaoshilei_yonghuzu': '\ue61b',
'add': '\ue664',
'add-circle': '\ue665',
'adjust': '\ue666',
'arrow-up-circle': '\ue667',
'arrow-right-circle': '\ue668',
'arrow-down': '\ue669',
'ashbin': '\ue66a',
'arrow-right': '\ue66b',
'browse': '\ue66c',
'bottom': '\ue66d',
'back': '\ue66e',
'bad': '\ue66f',
'arrow-left-circle': '\ue670',
'camera': '\ue671',
'chart-bar': '\ue672',
'attachment': '\ue673',
'code': '\ue674',
'close': '\ue675',
'check-item': '\ue676',
'calendar': '\ue677',
'comment': '\ue678',
'complete': '\ue679',
'direction-down': '\ue67a',
'direction-down-circle': '\ue67b',
'direction-right': '\ue67c',
'direction-up': '\ue67d',
'discount': '\ue67e',
'electronics': '\ue681',
'elipsis': '\ue682',
'export': '\ue683',
'explain': '\ue684',
'edit': '\ue685',
'eye-close': '\ue686',
'email': '\ue687',
'error': '\ue688',
'favorite': '\ue689',
'file-common': '\ue68a',
'file-delete': '\ue68b',
'file-add': '\ue68c',
'film': '\ue68d',
'fabulous': '\ue68e',
'file': '\ue68f',
'folder-close': '\ue690',
'filter': '\ue691',
'good': '\ue692',
'hide': '\ue693',
'home': '\ue694',
'file-open': '\ue695',
'forward': '\ue696',
'import': '\ue697',
'layers': '\ue698',
'lock': '\ue699',
'map': '\ue69a',
'menu': '\ue69b',
'help': '\ue69c',
'minus-circle': '\ue69d',
'notification': '\ue69e',
'more': '\ue69f',
'mobile-phone': '\ue6a0',
'minus': '\ue6a1',
'navigation': '\ue6a2',
'prompt': '\ue6a3',
'refresh': '\ue6a4',
'run-up': '\ue6a5',
'picture': '\ue6a6',
'run-in': '\ue6a7',
'pin': '\ue6a8',
'save': '\ue6a9',
'search': '\ue6aa',
'share': '\ue6ab',
'scanning': '\ue6ac',
'security': '\ue6ad',
'sign-out': '\ue6ae',
'select': '\ue6af',
'stop': '\ue6b0',
'success': '\ue6b1',
'switch': '\ue6b2',
'setting': '\ue6b3',
'survey': '\ue6b4',
'time': '\ue6b5',
'telephone': '\ue6b6',
'top': '\ue6b7',
'unlock': '\ue6b8',
// === 业务别名(兼容 lucide 等命名)===
'wallet': '\ue6c8',
'chevron-left': '\ue6c1',
'chevron-right': '\ue6c6',
'chevron-down': '\ue6c4',
'chevron-up': '\ue6c2',
'x': '\ue6c3',
'check': '\ue6c7',
'trash-2': '\ue66a',
'pencil': '\ue685',
'zap': '\ue75c',
'info': '\ue69c',
'map-pin': '\ue6a8',
'message-circle': '\ue678',
'smartphone': '\ue6a0',
'refresh-cw': '\ue6a4',
'shield': '\ue6ad',
'star': '\ue689',
'heart': '\ue68e',
'bar-chart': '\ue672',
'clock': '\ue6b5',
}
return map[name] || ''
},
// SVG 图标数据映射(Lucide 风格,替换原 emoji)
getSvgPath(name) {
const 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: ''
})
}
}
}
})