mirror of
https://github.com/atdunbg/Nekosonic-Music.git
synced 2026-08-11 15:24:18 +08:00
- 详情页统一 DetailLayout 组件(常驻头部 + 独立滚动 + 紧凑态动画) - 歌曲/评论 tab 切换(懒加载 + 保活),专辑模糊搜索 - 皮肤系统 skins.ts(19 语义色 + 14 预设 + 自定义皮肤 + 壁纸) - 设置页皮肤模块(外观/主题色/皮肤编辑器/壁纸选择) - 可折叠侧边栏 + TopBar + 折叠态歌单浮层(高度不越 PlayerBar) - 首页扩展至 6 区块 + 通用卡片组件 + 虚拟歌曲列表 - audio.rs 拆为 8 模块,api.ts 拆为 api/ 目录,player store 拆为 4 store - 修复播放竞态、seek 暂停、评论提前加载、紧凑态卡死等
60 lines
1.5 KiB
Vue
60 lines
1.5 KiB
Vue
<template>
|
|
<div class="grid gap-4" :class="gridClass">
|
|
<template v-if="loading && !items.length">
|
|
<div
|
|
v-for="i in skeletonCount"
|
|
:key="'skel-' + i"
|
|
class="rounded-xl overflow-hidden bg-subtle animate-pulse"
|
|
>
|
|
<div class="w-full aspect-square bg-muted"></div>
|
|
<div class="p-3 space-y-2">
|
|
<div class="h-4 bg-muted rounded w-3/4"></div>
|
|
<div class="h-3 bg-muted rounded w-1/2"></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<template v-else-if="error && !items.length">
|
|
<div class="col-span-full flex flex-col items-center justify-center py-12 gap-3">
|
|
<p class="text-content-2 text-sm">{{ errorText }}</p>
|
|
<button
|
|
@click="$emit('retry')"
|
|
class="px-4 py-2 bg-subtle hover:bg-muted rounded-lg text-sm transition"
|
|
>
|
|
重试
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<template v-else>
|
|
<slot />
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
|
|
const props = withDefaults(defineProps<{
|
|
items: unknown[];
|
|
loading?: boolean;
|
|
error?: boolean;
|
|
errorText?: string;
|
|
skeletonCount?: number;
|
|
/** 自定义栅格列数类名,默认响应式 */
|
|
gridClass?: string;
|
|
}>(), {
|
|
loading: false,
|
|
error: false,
|
|
errorText: '加载失败',
|
|
skeletonCount: 6,
|
|
gridClass: '',
|
|
});
|
|
|
|
const gridClass = computed(() => props.gridClass || 'grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6');
|
|
|
|
defineEmits<{
|
|
(e: 'retry'): void;
|
|
}>();
|
|
</script>
|