131 lines
3.0 KiB
Vue
131 lines
3.0 KiB
Vue
<template>
|
|
<div class="loading-container">
|
|
<!-- 产品卡片骨架屏 -->
|
|
<div v-if="type === 'product-card'" class="product-card-skeleton">
|
|
<div class="skeleton-header">
|
|
<el-skeleton-item variant="image" class="skeleton-image" />
|
|
<div class="skeleton-title">
|
|
<el-skeleton-item variant="h3" style="width: 50%" />
|
|
<el-skeleton-item variant="text" style="width: 30%; margin-top: 10px" />
|
|
</div>
|
|
</div>
|
|
<div class="skeleton-content">
|
|
<el-skeleton-item variant="text" style="width: 80%" />
|
|
<el-skeleton-item variant="text" style="width: 60%" />
|
|
<el-skeleton-item variant="text" style="width: 40%" />
|
|
</div>
|
|
<div class="skeleton-footer">
|
|
<el-skeleton-item variant="button" style="width: 80px; height: 32px" />
|
|
<el-skeleton-item variant="button" style="width: 80px; height: 32px" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 表格骨架屏 -->
|
|
<div v-else-if="type === 'table'" class="table-skeleton">
|
|
<el-skeleton :rows="rows" animated />
|
|
</div>
|
|
|
|
<!-- 图表骨架屏 -->
|
|
<div v-else-if="type === 'chart'" class="chart-skeleton">
|
|
<el-skeleton-item variant="h3" style="width: 30%; margin-bottom: 20px" />
|
|
<div class="chart-placeholder">
|
|
<el-skeleton-item variant="rect" style="width: 100%; height: 300px" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 列表骨架屏 -->
|
|
<div v-else-if="type === 'list'" class="list-skeleton">
|
|
<div v-for="i in rows" :key="i" class="list-item">
|
|
<el-skeleton-item variant="circle" style="width: 40px; height: 40px" />
|
|
<div class="list-item-content">
|
|
<el-skeleton-item variant="h3" style="width: 60%" />
|
|
<el-skeleton-item variant="text" style="width: 80%" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 默认骨架屏 -->
|
|
<div v-else class="default-skeleton">
|
|
<el-skeleton :rows="rows" animated />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'LoadingSkeleton',
|
|
props: {
|
|
type: {
|
|
type: String,
|
|
default: 'default',
|
|
validator: (value) => [
|
|
'default', 'product-card', 'table', 'chart', 'list'
|
|
].includes(value)
|
|
},
|
|
rows: {
|
|
type: Number,
|
|
default: 5
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.loading-container {
|
|
padding: 20px;
|
|
}
|
|
|
|
.product-card-skeleton {
|
|
border: 1px solid #ebeef5;
|
|
border-radius: 4px;
|
|
padding: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.skeleton-header {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.skeleton-image {
|
|
width: 80px;
|
|
height: 80px;
|
|
margin-right: 16px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.skeleton-title {
|
|
flex: 1;
|
|
}
|
|
|
|
.skeleton-content {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.skeleton-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.chart-placeholder {
|
|
width: 100%;
|
|
height: 300px;
|
|
}
|
|
|
|
.list-skeleton {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
}
|
|
|
|
.list-item {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.list-item-content {
|
|
margin-left: 16px;
|
|
flex: 1;
|
|
}
|
|
</style> |