2025-12-18 13:50:39 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="empty-state">
|
|
|
|
|
<!-- Icon -->
|
2025-12-25 08:40:12 -08:00
|
|
|
<div
|
|
|
|
|
class="mb-5 flex h-20 w-20 items-center justify-center rounded-2xl bg-gray-100 dark:bg-dark-800"
|
|
|
|
|
>
|
2025-12-18 13:50:39 +08:00
|
|
|
<slot name="icon">
|
2025-12-25 08:40:12 -08:00
|
|
|
<component v-if="icon" :is="icon" class="empty-state-icon h-10 w-10" aria-hidden="true" />
|
2025-12-18 13:50:39 +08:00
|
|
|
<svg
|
|
|
|
|
v-else
|
2025-12-25 08:40:12 -08:00
|
|
|
class="empty-state-icon h-10 w-10"
|
2025-12-18 13:50:39 +08:00
|
|
|
fill="none"
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
stroke-width="1.5"
|
|
|
|
|
>
|
|
|
|
|
<path
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"
|
|
|
|
|
/>
|
|
|
|
|
</svg>
|
|
|
|
|
</slot>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Title -->
|
|
|
|
|
<h3 class="empty-state-title">
|
2025-12-27 16:04:16 +08:00
|
|
|
{{ displayTitle }}
|
2025-12-18 13:50:39 +08:00
|
|
|
</h3>
|
|
|
|
|
|
|
|
|
|
<!-- Description -->
|
|
|
|
|
<p class="empty-state-description">
|
|
|
|
|
{{ description }}
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<!-- Action -->
|
|
|
|
|
<div v-if="actionText || $slots.action" class="mt-6">
|
|
|
|
|
<slot name="action">
|
|
|
|
|
<component
|
|
|
|
|
:is="actionTo ? 'RouterLink' : 'button'"
|
|
|
|
|
v-if="actionText"
|
|
|
|
|
:to="actionTo"
|
|
|
|
|
@click="!actionTo && $emit('action')"
|
|
|
|
|
class="btn btn-primary"
|
|
|
|
|
>
|
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 v-if="actionIcon" name="plus" size="md" class="mr-2" />
|
2025-12-18 13:50:39 +08:00
|
|
|
{{ actionText }}
|
|
|
|
|
</component>
|
|
|
|
|
</slot>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2025-12-27 16:04:16 +08:00
|
|
|
import { computed } from 'vue'
|
|
|
|
|
import { useI18n } from 'vue-i18n'
|
2025-12-18 13:50:39 +08:00
|
|
|
import type { Component } from 'vue'
|
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'
|
2025-12-18 13:50:39 +08:00
|
|
|
|
2025-12-27 16:04:16 +08:00
|
|
|
const { t } = useI18n()
|
|
|
|
|
|
2025-12-18 13:50:39 +08:00
|
|
|
interface Props {
|
|
|
|
|
icon?: Component | string
|
|
|
|
|
title?: string
|
|
|
|
|
description?: string
|
|
|
|
|
actionText?: string
|
|
|
|
|
actionTo?: string | object
|
|
|
|
|
actionIcon?: boolean
|
|
|
|
|
message?: string
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-27 16:04:16 +08:00
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
2025-12-18 13:50:39 +08:00
|
|
|
description: '',
|
|
|
|
|
actionIcon: true
|
|
|
|
|
})
|
|
|
|
|
|
2025-12-27 16:04:16 +08:00
|
|
|
const displayTitle = computed(() => props.title || t('common.noData'))
|
|
|
|
|
|
2025-12-18 13:50:39 +08:00
|
|
|
defineEmits(['action'])
|
|
|
|
|
</script>
|