const iconSvg = require('../../utils/icon-svg'); // 设计 token 色值映射:调用方常传 var(--xxx),但 SVG data URI 内无法解析 CSS 变量,需转成具体色值 const CSS_VARS = { '--accent': '#B6F24E', '--accent-hover': '#C7F56E', '--accent-active': '#9EDB3A', '--text': '#ECF1EF', '--text-2': '#9BA7A1', '--text-3': '#6B7670', '--danger': '#FF5C5C', '--success': '#2BD9A6', '--warn': '#F2B53D', '--info': '#4FA8FF', }; function resolveColor(c) { if (!c) return '#ECF1EF'; const m = /^var\((--[\w-]+)\)$/.exec(String(c).trim()); if (m) return CSS_VARS[m[1]] || '#ECF1EF'; return c; // 已是具体色值(hex) } // 用 渲染 Lucide SVG 矢量图(微信小程序 自定义字体不可靠,改用此方案 100% 稳定) Component({ properties: { // Lucide 图标名,如 search / dumbbell / heart name: { type: String, value: '' }, // 字号(rpx),同时作为图标宽高 size: { type: Number, value: 20 }, // 颜色:可传具体 hex,或 var(--xxx)(自动解析为对应 token 色值) color: { type: String, value: '' }, }, data: { src: '' }, observers: { name(n) { this._build(n, this.data.color); }, color(c) { this._build(this.data.name, c); }, }, lifetimes: { attached() { this._build(this.data.name, this.data.color); }, }, methods: { _build(name, color) { const inner = iconSvg[name]; if (!inner) { this.setData({ src: '' }); return; } const stroke = resolveColor(color); const body = inner.replace(/__C__/g, stroke); const svg = '' + body + ''; this.setData({ src: 'data:image/svg+xml,' + encodeURIComponent(svg) }); }, }, });