| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- import { ref } from "vue";
- export type IconItem = {
- type: 'iconfont'|'image'|'svg'|'none',
- value: string,
- rawSvg?: string,
- fontFamily?: string,
- };
- export type IconMap = Record<string, IconItem>;
- //图标集
- const iconMap = {} as IconMap;
- export const IconUtils = {
- iconCount: ref(0),
- /**
- * 设置 Icon 组件的图标名称映射。
- * 如果已存在同名数据,则会覆盖之前的。
- *
- * key是图标的名字,value 可以是以下几种情况:
- * * 是一个 iconfont:name 字符,则会渲染为字体形式的图标,通过 : 分割,前面是字体名称,后面是图标名称。
- * * 是一个 `data:***` 或者 http/https URL,则会尝试使用 Image 渲染为图片
- * * 是一个 `<svg` 开头的字符串,会渲染为 svg
- * * 否则,作为默认字体 iconfont 渲染为字体形式的图标。
- */
- configIconMap(map: Record<string, string>) {
- for (const key in map) {
- let result : IconItem;
- const v = map[key];
- if (v.startsWith('http') || v.startsWith('data:') || v.startsWith('/')) {
- result = {
- type: 'image',
- value: v,
- }
- } else if (v.startsWith('<svg') || v.includes('<svg')) {
- result = {
- type: 'svg',
- rawSvg: v,
- value: toDataSvg(v),
- }
- } else if (v.includes(':')) {
- const vv = v.split(':');
- result = {
- type: 'iconfont',
- value: vv[1],
- fontFamily: vv[0],
- }
- } else {
- result = {
- type: 'iconfont',
- value: v,
- }
- }
- iconMap[key] = result;
- }
- this.iconCount.value = Object.keys(iconMap).length;
- },
- getColoredSvg(svg: string, color: string) {
- return toDataSvg(
- svg.includes('fill=') ? svg : svg.replace(/<path /g, `<path fill="${color}" `)
- );
- },
- /**
- * 获取图标名称映射集
- * @returns
- */
- getIconMap() {
- return iconMap;
- },
- /**
- * 从图标名称映射中获取指定名称的图标数据。
- * @param key 图标名称
- * @returns 返回图标数据,如果找不到,返回 undefined。
- */
- getIconDataFromMap(key: string) {
- return iconMap[key];
- },
- /**
- * 加载默认图标。可选从本地或者网络加载。
- * @param urlOrJson 图标URL或者JSON字符串
- */
- async loadDefaultIcons(urlOrJson: string | Record<string, string>) : Promise<void> {
- if (typeof urlOrJson === 'object') {
- this.configIconMap(urlOrJson);
- return;
- }
- if (urlOrJson.startsWith('http') || urlOrJson.startsWith('https')) {
- return await new Promise((resolve, reject) => {
- uni.request({
- url: urlOrJson,
- method: 'GET',
- success: (res) => {
- this.configIconMap(typeof res.data === 'string' ? JSON.parse(res.data) : res.data);
- resolve();
- },
- fail: (err) => {
- console.error('加载默认图标失败', err);
- reject(err);
- },
- });
- });
- } else {
- this.configIconMap(JSON.parse(urlOrJson));
- }
- },
- }
- function toDataSvg(str: string) {
- if (!str.includes('xmlns'))
- str = str.replace("<svg ", "<svg xmlns='http://www.w3.org/2000/svg' ");
- return `data:image/svg+xml,${encodeURIComponent(str.replace(/\'/g, '"'))}`.replace(/\#/g, '%23');
- }
|