2026-01-04 22:29:19 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="relative w-full">
|
|
|
|
|
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
refactor(frontend): 完成所有组件的内联SVG统一替换为Icon组件
- 扩展 Icon.vue 组件,新增 60+ 图标路径
- 导航类: arrowRight, arrowLeft, arrowUp, arrowDown, chevronUp, externalLink
- 状态类: checkCircle, xCircle, exclamationCircle, exclamationTriangle, infoCircle
- 用户类: user, userCircle, userPlus, users
- 文档类: document, clipboard, copy, inbox
- 操作类: download, upload, filter, sort
- 安全类: key, lock, shield
- UI类: menu, calendar, home, terminal, gift, creditCard, mail
- 数据类: chartBar, trendingUp, database, cube
- 其他: bolt, sparkles, cloud, server, sun, moon, book 等
- 重构 56 个 Vue 组件,用 Icon 组件替换内联 SVG
- 净减少约 2200 行代码
- 提升代码可维护性和一致性
- 统一图标样式和尺寸管理
2026-01-05 20:22:48 +08:00
|
|
|
<Icon name="search" size="md" class="text-gray-400" />
|
2026-01-04 22:29:19 +08:00
|
|
|
</div>
|
|
|
|
|
<input
|
|
|
|
|
:value="modelValue"
|
|
|
|
|
type="text"
|
|
|
|
|
class="input pl-10"
|
|
|
|
|
:placeholder="placeholder"
|
|
|
|
|
@input="handleInput"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { useDebounceFn } from '@vueuse/core'
|
refactor(frontend): 完成所有组件的内联SVG统一替换为Icon组件
- 扩展 Icon.vue 组件,新增 60+ 图标路径
- 导航类: arrowRight, arrowLeft, arrowUp, arrowDown, chevronUp, externalLink
- 状态类: checkCircle, xCircle, exclamationCircle, exclamationTriangle, infoCircle
- 用户类: user, userCircle, userPlus, users
- 文档类: document, clipboard, copy, inbox
- 操作类: download, upload, filter, sort
- 安全类: key, lock, shield
- UI类: menu, calendar, home, terminal, gift, creditCard, mail
- 数据类: chartBar, trendingUp, database, cube
- 其他: bolt, sparkles, cloud, server, sun, moon, book 等
- 重构 56 个 Vue 组件,用 Icon 组件替换内联 SVG
- 净减少约 2200 行代码
- 提升代码可维护性和一致性
- 统一图标样式和尺寸管理
2026-01-05 20:22:48 +08:00
|
|
|
import Icon from '@/components/icons/Icon.vue'
|
2026-01-04 22:29:19 +08:00
|
|
|
|
|
|
|
|
const props = withDefaults(defineProps<{
|
|
|
|
|
modelValue: string
|
|
|
|
|
placeholder?: string
|
|
|
|
|
debounceMs?: number
|
|
|
|
|
}>(), {
|
|
|
|
|
placeholder: 'Search...',
|
|
|
|
|
debounceMs: 300
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
|
(e: 'update:modelValue', value: string): void
|
|
|
|
|
(e: 'search', value: string): void
|
|
|
|
|
}>()
|
|
|
|
|
|
|
|
|
|
const debouncedEmitSearch = useDebounceFn((value: string) => {
|
|
|
|
|
emit('search', value)
|
|
|
|
|
}, props.debounceMs)
|
|
|
|
|
|
|
|
|
|
const handleInput = (event: Event) => {
|
|
|
|
|
const value = (event.target as HTMLInputElement).value
|
|
|
|
|
emit('update:modelValue', value)
|
|
|
|
|
debouncedEmitSearch(value)
|
|
|
|
|
}
|
|
|
|
|
</script>
|