51 lines
1.4 KiB
JavaScript
51 lines
1.4 KiB
JavaScript
/**
|
|
* Lucide 图标注册表 — 懒加载所有图标并按名称查找。
|
|
* 首次使用时动态 import('@lucide/vue'),之后缓存复用。
|
|
* iconMap 为响应式 ref,加载完成后自动触发依赖它的 computed 重算。
|
|
*/
|
|
import { ref } from "vue";
|
|
|
|
const iconMap = ref(null);
|
|
let loadingPromise = null;
|
|
const KNOWN_NON_ICONS = new Set(["createLucideIcon"]);
|
|
|
|
async function ensureLoaded() {
|
|
if (iconMap.value) return iconMap.value;
|
|
if (!loadingPromise) {
|
|
loadingPromise = import("@lucide/vue").then((mod) => {
|
|
const map = {};
|
|
for (const [key, component] of Object.entries(mod)) {
|
|
if (!KNOWN_NON_ICONS.has(key) && key[0] === key[0].toUpperCase()) {
|
|
map[key] = component;
|
|
}
|
|
}
|
|
iconMap.value = map;
|
|
return map;
|
|
});
|
|
}
|
|
return loadingPromise;
|
|
}
|
|
|
|
/** 获取所有图标名称(按字母排序),需要 await */
|
|
export async function getIconNames() {
|
|
const map = await ensureLoaded();
|
|
return Object.keys(map).sort();
|
|
}
|
|
|
|
/** 同步获取图标组件;响应式,加载完成后自动重算依赖的 computed */
|
|
export function getIcon(name) {
|
|
if (!iconMap.value || !name) return null;
|
|
return iconMap.value[name] || null;
|
|
}
|
|
|
|
/** 异步获取图标组件 */
|
|
export async function getIconAsync(name) {
|
|
const map = await ensureLoaded();
|
|
return map[name] || null;
|
|
}
|
|
|
|
/** 图标是否已加载完成 */
|
|
export function isLoaded() {
|
|
return iconMap.value !== null;
|
|
}
|