11<script setup lang="ts">
2- import { mapEntries } from ' radash'
3-
42interface Props {
53 disabled? : boolean
64}
@@ -14,12 +12,13 @@ interface IconList {
1412 icons: string []
1513 title: string
1614 total: number
17- categories: Record <string , string []>
15+ categories? : Record <string , string []>
16+ uncategorized? : string []
1817}
1918const value = defineModel (' value' , { type: String })
2019
21- // 包含的图标库系列名
22- const nameList = [' icon-park-outline' , ' carbon' ]
20+ // 包含的图标库系列名,更多:https://icon-sets.iconify.design/
21+ const nameList = [' icon-park-outline' , ' carbon' , ' ant-design ' ]
2322
2423// 获取单个图标库数据
2524async function fetchIconList(name : string ): Promise <IconList > {
@@ -28,65 +27,59 @@ async function fetchIconList(name: string): Promise<IconList> {
2827
2928// 获取所有图标库数据
3029async function fetchIconAllList(nameList : string []) {
31- const namePromises = nameList .map (name => fetchIconList (name ))
32- const targets = await Promise .all (namePromises )
33-
34- return targets .map ((i ) => {
35- i .icons = Object .entries (i .categories ).reduce ((prev , next ) => {
36- const [_key, value] = next
37- return prev .concat (value )
38- }, [] as string [])
39- return i
30+ // 并行请求所有图标列表
31+ const targets = await Promise .all (nameList .map (fetchIconList ))
32+
33+ // 处理每个返回的图标数据
34+ const iconList = targets .map ((item ) => {
35+ const icons = [
36+ ... (item .categories ? Object .values (item .categories ).flat () : []),
37+ ... (item .uncategorized ? Object .values (item .uncategorized ).flat () : []),
38+ ]
39+ return { ... item , icons }
4040 })
41- }
42- // 获取svg文件名
43- function getSvgName(path : string ) {
44- const regex = / \/ ([^ /] + )\. svg$ /
45- const match = path .match (regex )
46- if (match ) {
47- const fileName = match [1 ]
48- return fileName
49- }
50- return path
51- }
5241
53- // 获取所有本地图标
54- function generateLocalIconList() {
55- const localSvgList = import .meta .glob (' @/assets/svg-icons/*.svg' , {
56- query: ' ?raw' ,
57- import: ' default' ,
58- eager: true ,
42+ // 处理本地图标
43+ const svgNames = Object .keys (import .meta .glob (' @/assets/svg-icons/*.svg' )).map (
44+ path => path .split (' /' ).pop ()?.replace (' .svg' , ' ' ),
45+ ).filter (Boolean ) as string [] // 过滤掉 undefined 并断言为 string[]
46+
47+ // 在数组开头添加
48+ iconList .unshift ({
49+ prefix: ' local' ,
50+ title: ' Local Icons' ,
51+ icons: svgNames ,
52+ total: svgNames .length ,
53+ uncategorized: svgNames ,
5954 })
6055
61- return mapEntries (localSvgList , (key , value ) => {
62- return [getSvgName (key ), value ]
63- })
56+ return iconList
6457}
6558
6659const iconList = shallowRef <IconList []>([])
67- const LocalIconList = shallowRef ({})
6860
6961onMounted (async () => {
7062 iconList .value = await fetchIconAllList (nameList )
71- LocalIconList .value = generateLocalIconList ()
7263})
7364
7465// 当前tab
7566const currentTab = shallowRef (0 )
7667// 当前tag
7768const currentTag = shallowRef (' ' )
7869
79- // 切换tab
80- function handleChangeTab(index : number ) {
81- currentTab .value = index
82- currentTag .value = ' '
83- }
8470// 搜索图标输入框值
8571const searchValue = ref (' ' )
8672
8773// 当前页数
8874const currentPage = shallowRef (1 )
8975
76+ // 切换tab
77+ function handleChangeTab(index : number ) {
78+ currentTab .value = index
79+ currentTag .value = ' '
80+ currentPage .value = 1
81+ }
82+
9083// 选择分类tag
9184function handleSelectIconTag(icon : string ) {
9285 currentTag .value = currentTag .value === icon ? ' ' : icon
@@ -99,7 +92,7 @@ const icons = computed(() => {
9992 return []
10093 const hasTag = !! currentTag .value
10194 return hasTag
102- ? iconList .value [currentTab .value ]?.categories [currentTag .value ] || []
95+ ? iconList .value [currentTab .value ]?.categories ?. [currentTag .value ] || [] // 使用可选链
10396 : iconList .value [currentTab .value ].icons || []
10497})
10598
@@ -150,18 +143,6 @@ function clearIcon() {
150143 </template >
151144
152145 <n-tabs :value =" currentTab" type =" line" animated placement =" left" @update:value =" handleChangeTab" >
153- <n-tab-pane name =" local" tab =" local" >
154- <n-flex :size =" 2" >
155- <n-el
156- v-for =" (_icon, key) in LocalIconList" :key =" key"
157- class =" hover:(text-[var(--primary-color)] ring-1) ring-[var(--primary-color)] p-1 rounded flex-center"
158- :title =" `local:${key}`"
159- @click =" handleSelectIcon(`local:${key}`)"
160- >
161- <nova-icon :icon =" `local:${key}`" :size =" 24" />
162- </n-el >
163- </n-flex >
164- </n-tab-pane >
165146 <n-tab-pane v-for =" (list, index) in iconList" :key =" list.prefix" :name =" index" :tab =" list.title" >
166147 <n-flex vertical >
167148 <n-flex size =" small" >
0 commit comments