Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3e4e900

Browse files
committed
feat: 更新IconSelect组件,支持未分类图标并优化图标数据处理逻辑
1 parent bc968dc commit 3e4e900

File tree

1 file changed

+35
-54
lines changed

1 file changed

+35
-54
lines changed

src/components/common/IconSelect.vue

Lines changed: 35 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
<script setup lang="ts">
2-
import { mapEntries } from 'radash'
3-
42
interface 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
}
1918
const 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
// 获取单个图标库数据
2524
async function fetchIconList(name: string): Promise<IconList> {
@@ -28,65 +27,59 @@ async function fetchIconList(name: string): Promise<IconList> {
2827
2928
// 获取所有图标库数据
3029
async 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
6659
const iconList = shallowRef<IconList[]>([])
67-
const LocalIconList = shallowRef({})
6860
6961
onMounted(async () => {
7062
iconList.value = await fetchIconAllList(nameList)
71-
LocalIconList.value = generateLocalIconList()
7263
})
7364
7465
// 当前tab
7566
const currentTab = shallowRef(0)
7667
// 当前tag
7768
const currentTag = shallowRef('')
7869
79-
// 切换tab
80-
function handleChangeTab(index: number) {
81-
currentTab.value = index
82-
currentTag.value = ''
83-
}
8470
// 搜索图标输入框值
8571
const searchValue = ref('')
8672
8773
// 当前页数
8874
const 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
9184
function 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

Comments
 (0)