665 行
15 KiB
Vue
665 行
15 KiB
Vue
<template>
|
|
<view class="skeleton-wrap" :class="[themeClass]">
|
|
<!-- 1. 首页骨架屏 (type === 'home') -->
|
|
<view v-if="type === 'home'" class="skeleton-home">
|
|
<!-- 轮播图骨架 -->
|
|
<view class="skeleton-banner skeleton-shimmer" />
|
|
|
|
<!-- 金刚区 8 宫格骨架 -->
|
|
<view class="skeleton-grid">
|
|
<view v-for="i in 8" :key="i" class="skeleton-grid-item">
|
|
<view class="skeleton-circle skeleton-shimmer" />
|
|
<view class="skeleton-bar-sm skeleton-shimmer" />
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 推荐大神流骨架 -->
|
|
<view class="skeleton-sec-header">
|
|
<view class="skeleton-bar-md skeleton-shimmer" />
|
|
<view class="skeleton-bar-sm skeleton-shimmer" />
|
|
</view>
|
|
|
|
<view class="skeleton-card-list">
|
|
<view v-for="i in 3" :key="i" class="skeleton-expert-card">
|
|
<view class="card-top">
|
|
<view class="card-avatar skeleton-shimmer" />
|
|
<view class="card-info">
|
|
<view class="skeleton-bar-lg skeleton-shimmer" />
|
|
<view class="card-tags">
|
|
<view class="skeleton-pill skeleton-shimmer" />
|
|
<view class="skeleton-pill skeleton-shimmer" />
|
|
</view>
|
|
<view class="skeleton-bar-sm skeleton-shimmer" />
|
|
</view>
|
|
</view>
|
|
<view class="card-voice skeleton-shimmer" />
|
|
<view class="card-bottom">
|
|
<view class="skeleton-bar-md skeleton-shimmer" />
|
|
<view class="skeleton-btn skeleton-shimmer" />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 2. 活动大厅骨架屏 (type === 'activity') -->
|
|
<view v-else-if="type === 'activity'" class="skeleton-activity">
|
|
<!-- 搜索栏骨架 -->
|
|
<view class="skeleton-search-bar skeleton-shimmer" />
|
|
|
|
<!-- 分类胶囊栏骨架 -->
|
|
<view class="skeleton-capsules">
|
|
<view v-for="i in 5" :key="i" class="skeleton-capsule-item skeleton-shimmer" />
|
|
</view>
|
|
|
|
<!-- 组局卡片骨架列表 -->
|
|
<view class="skeleton-activity-list">
|
|
<view v-for="i in 3" :key="i" class="skeleton-activity-card">
|
|
<view class="act-header">
|
|
<view class="act-leader-avatar skeleton-shimmer" />
|
|
<view class="act-header-info">
|
|
<view class="skeleton-bar-lg skeleton-shimmer" />
|
|
<view class="skeleton-bar-sm skeleton-shimmer" />
|
|
</view>
|
|
<view class="skeleton-pill skeleton-shimmer" />
|
|
</view>
|
|
<view class="act-location skeleton-shimmer" />
|
|
<view class="act-footer">
|
|
<view class="act-avatars-cluster">
|
|
<view v-for="j in 3" :key="j" class="act-user-circle skeleton-shimmer" />
|
|
</view>
|
|
<view class="skeleton-bar-md skeleton-shimmer" />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 3. 友圈广场骨架屏 (type === 'community') -->
|
|
<view v-else-if="type === 'community'" class="skeleton-community">
|
|
<!-- 分类标签骨架 -->
|
|
<view class="skeleton-tabs">
|
|
<view v-for="i in 4" :key="i" class="skeleton-tab-item skeleton-shimmer" />
|
|
</view>
|
|
|
|
<!-- 动态卡片列表骨架 -->
|
|
<view class="skeleton-post-list">
|
|
<view v-for="i in 2" :key="i" class="skeleton-post-card">
|
|
<view class="post-header">
|
|
<view class="post-avatar skeleton-shimmer" />
|
|
<view class="post-user-info">
|
|
<view class="skeleton-bar-md skeleton-shimmer" />
|
|
<view class="skeleton-bar-sm skeleton-shimmer" />
|
|
</view>
|
|
<view class="skeleton-pill skeleton-shimmer" />
|
|
</view>
|
|
<view class="post-text-lines">
|
|
<view class="skeleton-bar-full skeleton-shimmer" />
|
|
<view class="skeleton-bar-sub skeleton-shimmer" />
|
|
</view>
|
|
<view class="post-images-grid">
|
|
<view class="post-img-box skeleton-shimmer" />
|
|
<view class="post-img-box skeleton-shimmer" />
|
|
</view>
|
|
<view class="post-actions-bar">
|
|
<view class="action-slot skeleton-shimmer" />
|
|
<view class="action-slot skeleton-shimmer" />
|
|
<view class="action-slot skeleton-shimmer" />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 4. 大神主页骨架屏 (type === 'expert') -->
|
|
<view v-else-if="type === 'expert'" class="skeleton-expert">
|
|
<view class="expert-hero skeleton-shimmer" />
|
|
<view class="expert-profile-box">
|
|
<view class="expert-avatar-large skeleton-shimmer" />
|
|
<view class="skeleton-bar-lg skeleton-shimmer" />
|
|
<view class="expert-tags-row">
|
|
<view class="skeleton-pill skeleton-shimmer" />
|
|
<view class="skeleton-pill skeleton-shimmer" />
|
|
<view class="skeleton-pill skeleton-shimmer" />
|
|
</view>
|
|
<view class="expert-voice-bar skeleton-shimmer" />
|
|
</view>
|
|
<view class="expert-services-box">
|
|
<view class="skeleton-bar-md skeleton-shimmer" />
|
|
<view class="skeleton-service-card skeleton-shimmer" />
|
|
<view class="skeleton-service-card skeleton-shimmer" />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue';
|
|
import { getCurrentThemeKey } from '@/common/theme.js';
|
|
|
|
const props = defineProps({
|
|
type: {
|
|
type: String,
|
|
default: 'home'
|
|
},
|
|
theme: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
});
|
|
|
|
const themeClass = computed(() => {
|
|
const activeTheme = props.theme || getCurrentThemeKey();
|
|
return activeTheme === 'warm' ? 'theme-warm' : 'theme-cool';
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@keyframes skeletonShimmer {
|
|
0% {
|
|
background-position: 100% 50%;
|
|
}
|
|
100% {
|
|
background-position: 0 50%;
|
|
}
|
|
}
|
|
|
|
.skeleton-shimmer {
|
|
background: linear-gradient(
|
|
90deg,
|
|
rgba(255, 255, 255, 0.04) 25%,
|
|
rgba(255, 255, 255, 0.12) 37%,
|
|
rgba(255, 255, 255, 0.04) 63%
|
|
);
|
|
background-size: 400% 100%;
|
|
animation: skeletonShimmer 1.5s ease infinite;
|
|
}
|
|
|
|
.skeleton-wrap {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
// 1. 首页骨架屏样式
|
|
.skeleton-home {
|
|
padding: 16rpx 32rpx;
|
|
|
|
.skeleton-banner {
|
|
width: 100%;
|
|
height: 320rpx;
|
|
border-radius: 24rpx;
|
|
margin-bottom: 32rpx;
|
|
}
|
|
|
|
.skeleton-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 24rpx 16rpx;
|
|
background: rgba(255, 255, 255, 0.03);
|
|
border-radius: 24rpx;
|
|
padding: 28rpx 16rpx;
|
|
margin-bottom: 36rpx;
|
|
|
|
.skeleton-grid-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 12rpx;
|
|
|
|
.skeleton-circle {
|
|
width: 88rpx;
|
|
height: 88rpx;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.skeleton-bar-sm {
|
|
width: 80rpx;
|
|
height: 20rpx;
|
|
border-radius: 10rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.skeleton-sec-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 24rpx;
|
|
|
|
.skeleton-bar-md {
|
|
width: 180rpx;
|
|
height: 36rpx;
|
|
border-radius: 18rpx;
|
|
}
|
|
.skeleton-bar-sm {
|
|
width: 100rpx;
|
|
height: 24rpx;
|
|
border-radius: 12rpx;
|
|
}
|
|
}
|
|
|
|
.skeleton-card-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 24rpx;
|
|
|
|
.skeleton-expert-card {
|
|
background: rgba(255, 255, 255, 0.03);
|
|
border-radius: 24rpx;
|
|
padding: 24rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 18rpx;
|
|
|
|
.card-top {
|
|
display: flex;
|
|
gap: 20rpx;
|
|
|
|
.card-avatar {
|
|
width: 120rpx;
|
|
height: 120rpx;
|
|
border-radius: 20rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.card-info {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12rpx;
|
|
|
|
.skeleton-bar-lg {
|
|
width: 220rpx;
|
|
height: 32rpx;
|
|
border-radius: 16rpx;
|
|
}
|
|
|
|
.card-tags {
|
|
display: flex;
|
|
gap: 12rpx;
|
|
|
|
.skeleton-pill {
|
|
width: 90rpx;
|
|
height: 32rpx;
|
|
border-radius: 16rpx;
|
|
}
|
|
}
|
|
|
|
.skeleton-bar-sm {
|
|
width: 140rpx;
|
|
height: 20rpx;
|
|
border-radius: 10rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.card-voice {
|
|
width: 100%;
|
|
height: 60rpx;
|
|
border-radius: 30rpx;
|
|
}
|
|
|
|
.card-bottom {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
|
|
.skeleton-bar-md {
|
|
width: 140rpx;
|
|
height: 36rpx;
|
|
border-radius: 18rpx;
|
|
}
|
|
.skeleton-btn {
|
|
width: 150rpx;
|
|
height: 56rpx;
|
|
border-radius: 28rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. 活动大厅骨架屏样式
|
|
.skeleton-activity {
|
|
padding: 16rpx 32rpx;
|
|
|
|
.skeleton-search-bar {
|
|
width: 100%;
|
|
height: 76rpx;
|
|
border-radius: 38rpx;
|
|
margin-bottom: 24rpx;
|
|
}
|
|
|
|
.skeleton-capsules {
|
|
display: flex;
|
|
gap: 16rpx;
|
|
margin-bottom: 32rpx;
|
|
overflow-x: hidden;
|
|
|
|
.skeleton-capsule-item {
|
|
width: 130rpx;
|
|
height: 56rpx;
|
|
border-radius: 28rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
}
|
|
|
|
.skeleton-activity-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 24rpx;
|
|
|
|
.skeleton-activity-card {
|
|
background: rgba(255, 255, 255, 0.03);
|
|
border-radius: 24rpx;
|
|
padding: 28rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 18rpx;
|
|
|
|
.act-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16rpx;
|
|
|
|
.act-leader-avatar {
|
|
width: 64rpx;
|
|
height: 64rpx;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.act-header-info {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10rpx;
|
|
|
|
.skeleton-bar-lg {
|
|
width: 320rpx;
|
|
height: 30rpx;
|
|
border-radius: 15rpx;
|
|
}
|
|
.skeleton-bar-sm {
|
|
width: 160rpx;
|
|
height: 20rpx;
|
|
border-radius: 10rpx;
|
|
}
|
|
}
|
|
|
|
.skeleton-pill {
|
|
width: 110rpx;
|
|
height: 40rpx;
|
|
border-radius: 20rpx;
|
|
}
|
|
}
|
|
|
|
.act-location {
|
|
width: 80%;
|
|
height: 26rpx;
|
|
border-radius: 13rpx;
|
|
}
|
|
|
|
.act-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding-top: 12rpx;
|
|
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
|
|
|
.act-avatars-cluster {
|
|
display: flex;
|
|
|
|
.act-user-circle {
|
|
width: 48rpx;
|
|
height: 48rpx;
|
|
border-radius: 50%;
|
|
margin-right: -12rpx;
|
|
}
|
|
}
|
|
|
|
.skeleton-bar-md {
|
|
width: 160rpx;
|
|
height: 36rpx;
|
|
border-radius: 18rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 3. 友圈广场骨架屏样式
|
|
.skeleton-community {
|
|
padding: 16rpx 32rpx;
|
|
|
|
.skeleton-tabs {
|
|
display: flex;
|
|
gap: 16rpx;
|
|
margin-bottom: 28rpx;
|
|
|
|
.skeleton-tab-item {
|
|
width: 140rpx;
|
|
height: 60rpx;
|
|
border-radius: 30rpx;
|
|
}
|
|
}
|
|
|
|
.skeleton-post-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 28rpx;
|
|
|
|
.skeleton-post-card {
|
|
background: rgba(255, 255, 255, 0.03);
|
|
border-radius: 24rpx;
|
|
padding: 28rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20rpx;
|
|
|
|
.post-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 18rpx;
|
|
|
|
.post-avatar {
|
|
width: 76rpx;
|
|
height: 76rpx;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.post-user-info {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8rpx;
|
|
|
|
.skeleton-bar-md {
|
|
width: 180rpx;
|
|
height: 28rpx;
|
|
border-radius: 14rpx;
|
|
}
|
|
.skeleton-bar-sm {
|
|
width: 120rpx;
|
|
height: 20rpx;
|
|
border-radius: 10rpx;
|
|
}
|
|
}
|
|
|
|
.skeleton-pill {
|
|
width: 110rpx;
|
|
height: 36rpx;
|
|
border-radius: 18rpx;
|
|
}
|
|
}
|
|
|
|
.post-text-lines {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12rpx;
|
|
|
|
.skeleton-bar-full {
|
|
width: 100%;
|
|
height: 26rpx;
|
|
border-radius: 13rpx;
|
|
}
|
|
.skeleton-bar-sub {
|
|
width: 70%;
|
|
height: 26rpx;
|
|
border-radius: 13rpx;
|
|
}
|
|
}
|
|
|
|
.post-images-grid {
|
|
display: flex;
|
|
gap: 16rpx;
|
|
|
|
.post-img-box {
|
|
width: 220rpx;
|
|
height: 200rpx;
|
|
border-radius: 16rpx;
|
|
}
|
|
}
|
|
|
|
.post-actions-bar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding-top: 16rpx;
|
|
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
|
|
|
.action-slot {
|
|
width: 120rpx;
|
|
height: 32rpx;
|
|
border-radius: 16rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 4. 大神详情骨架屏样式
|
|
.skeleton-expert {
|
|
.expert-hero {
|
|
width: 100%;
|
|
height: 420rpx;
|
|
}
|
|
|
|
.expert-profile-box {
|
|
padding: 32rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 18rpx;
|
|
margin-top: -60rpx;
|
|
background: rgba(21, 29, 48, 0.95);
|
|
border-radius: 36rpx 36rpx 0 0;
|
|
|
|
.expert-avatar-large {
|
|
width: 140rpx;
|
|
height: 140rpx;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.skeleton-bar-lg {
|
|
width: 240rpx;
|
|
height: 36rpx;
|
|
border-radius: 18rpx;
|
|
}
|
|
|
|
.expert-tags-row {
|
|
display: flex;
|
|
gap: 14rpx;
|
|
|
|
.skeleton-pill {
|
|
width: 120rpx;
|
|
height: 36rpx;
|
|
border-radius: 18rpx;
|
|
}
|
|
}
|
|
|
|
.expert-voice-bar {
|
|
width: 90%;
|
|
height: 64rpx;
|
|
border-radius: 32rpx;
|
|
margin-top: 10rpx;
|
|
}
|
|
}
|
|
|
|
.expert-services-box {
|
|
padding: 32rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20rpx;
|
|
|
|
.skeleton-bar-md {
|
|
width: 180rpx;
|
|
height: 34rpx;
|
|
border-radius: 17rpx;
|
|
}
|
|
|
|
.skeleton-service-card {
|
|
width: 100%;
|
|
height: 120rpx;
|
|
border-radius: 20rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 5. 暖色系适配 (theme-warm)
|
|
.theme-warm {
|
|
.skeleton-shimmer {
|
|
background: linear-gradient(
|
|
90deg,
|
|
#F3EFEA 25%,
|
|
#E5DFD7 37%,
|
|
#F3EFEA 63%
|
|
);
|
|
background-size: 400% 100%;
|
|
}
|
|
|
|
.skeleton-home {
|
|
.skeleton-grid {
|
|
background: #FFFFFF;
|
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
|
|
}
|
|
.skeleton-card-list {
|
|
.skeleton-expert-card {
|
|
background: #FFFFFF;
|
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
|
|
}
|
|
}
|
|
}
|
|
|
|
.skeleton-activity {
|
|
.skeleton-activity-list {
|
|
.skeleton-activity-card {
|
|
background: #FFFFFF;
|
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
|
|
|
|
.act-footer {
|
|
border-top-color: #F5F2EC;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.skeleton-community {
|
|
.skeleton-post-list {
|
|
.skeleton-post-card {
|
|
background: #FFFFFF;
|
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
|
|
|
|
.post-actions-bar {
|
|
border-top-color: #F5F2EC;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.skeleton-expert {
|
|
.expert-profile-box {
|
|
background: #FFFFFF;
|
|
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.04);
|
|
}
|
|
}
|
|
}
|
|
</style>
|