- 新增分包组件 ListSkeleton(doctor/message/product/article/category/zone) - 首页/消息/资讯首次加载改用骨架屏,刷新不再清空旧数据避免闪空 · 去掉 home getList、消息 onShow 中的数组清空 · 三页 pages.json 增加 easycom 与 componentPlaceholder 主包异步引用 - 聊天室己方头像改为读取本地 userinfo.avatarurl(登录后微信头像), mycollection 上传头像成功后同步写回 storage - 修复协议抽屉点不开:page-container 改为 v-if + :show; 协议名单独可点节点,匹配放宽 name/desc 双向 includes - 医生气泡头像可点击进入 doctor-detail?readonly=1 只读医生详情, 隐藏预约挂号区
276 lines
5.3 KiB
Vue
276 lines
5.3 KiB
Vue
<template>
|
||
<!--
|
||
列表骨架屏:按 type 模拟医生卡/消息行/商品卡/资讯卡/分类侧栏,
|
||
放在分包以控制主包体积,主包页通过 componentPlaceholder 异步引用。
|
||
-->
|
||
<view class="list-skeleton" :class="'list-skeleton--' + type">
|
||
<view
|
||
v-for="i in rowCount"
|
||
:key="i"
|
||
class="sk-row"
|
||
:class="'sk-row--' + type"
|
||
>
|
||
<!-- 医生推荐卡片 -->
|
||
<template v-if="type === 'doctor'">
|
||
<view class="sk-avatar sk-shimmer"></view>
|
||
<view class="sk-body">
|
||
<view class="sk-line sk-line--lg sk-shimmer"></view>
|
||
<view class="sk-line sk-line--md sk-shimmer"></view>
|
||
<view class="sk-line sk-line--sm sk-shimmer"></view>
|
||
</view>
|
||
</template>
|
||
<!-- 消息列表行 -->
|
||
<template v-else-if="type === 'message'">
|
||
<view class="sk-avatar sk-avatar--round sk-shimmer"></view>
|
||
<view class="sk-body">
|
||
<view class="sk-line-row">
|
||
<view class="sk-line sk-line--md sk-shimmer"></view>
|
||
<view class="sk-line sk-line--xs sk-shimmer"></view>
|
||
</view>
|
||
<view class="sk-line sk-line--sm sk-shimmer"></view>
|
||
</view>
|
||
</template>
|
||
<!-- 商品卡片 -->
|
||
<template v-else-if="type === 'product'">
|
||
<view class="sk-prod-img sk-shimmer"></view>
|
||
<view class="sk-body">
|
||
<view class="sk-line sk-line--lg sk-shimmer"></view>
|
||
<view class="sk-line sk-line--sm sk-shimmer"></view>
|
||
<view class="sk-line sk-line--md sk-shimmer"></view>
|
||
</view>
|
||
</template>
|
||
<!-- 资讯文章卡片 -->
|
||
<template v-else-if="type === 'article'">
|
||
<view class="sk-cover sk-shimmer"></view>
|
||
<view class="sk-cover-title sk-shimmer"></view>
|
||
</template>
|
||
<!-- 资讯左侧分类 -->
|
||
<template v-else-if="type === 'category'">
|
||
<view class="sk-cate-item sk-shimmer"></view>
|
||
</template>
|
||
<!-- 金刚区横滑块 -->
|
||
<template v-else-if="type === 'zone'">
|
||
<view class="sk-zone-icon sk-shimmer"></view>
|
||
<view class="sk-line sk-line--xs sk-shimmer"></view>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'ListSkeleton',
|
||
props: {
|
||
// 骨架样式类型
|
||
type: {
|
||
type: String,
|
||
default: 'message',
|
||
validator(v) {
|
||
return ['doctor', 'message', 'product', 'article', 'category', 'zone'].indexOf(v) !== -1
|
||
}
|
||
},
|
||
// 行数
|
||
rows: {
|
||
type: [Number, String],
|
||
default: 3
|
||
}
|
||
},
|
||
computed: {
|
||
rowCount() {
|
||
const n = Number(this.rows)
|
||
return n > 0 ? n : 3
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.list-skeleton {
|
||
width: 100%;
|
||
}
|
||
|
||
.sk-shimmer {
|
||
background: linear-gradient(90deg, #ebebeb 25%, #f5f5f5 50%, #ebebeb 75%);
|
||
background-size: 400% 100%;
|
||
animation: sk-shimmer 1.4s ease infinite;
|
||
}
|
||
|
||
@keyframes sk-shimmer {
|
||
0% {
|
||
background-position: 100% 0;
|
||
}
|
||
100% {
|
||
background-position: 0 0;
|
||
}
|
||
}
|
||
|
||
.sk-row--doctor {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
margin: 0 24rpx 20rpx;
|
||
padding: 28rpx;
|
||
background: #fff;
|
||
border-radius: 24rpx;
|
||
|
||
.sk-avatar {
|
||
width: 96rpx;
|
||
height: 96rpx;
|
||
border-radius: 50%;
|
||
flex-shrink: 0;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.sk-body {
|
||
flex: 1;
|
||
}
|
||
}
|
||
|
||
.sk-row--message {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 32rpx 38rpx;
|
||
background: #fff;
|
||
|
||
.sk-avatar {
|
||
width: 84rpx;
|
||
height: 84rpx;
|
||
border-radius: 50%;
|
||
flex-shrink: 0;
|
||
margin-right: 24rpx;
|
||
}
|
||
|
||
.sk-body {
|
||
flex: 1;
|
||
}
|
||
|
||
.sk-line-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
}
|
||
|
||
.sk-row--product {
|
||
display: flex;
|
||
margin: 0 24rpx 20rpx;
|
||
padding: 20rpx;
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
|
||
.sk-prod-img {
|
||
width: 160rpx;
|
||
height: 160rpx;
|
||
border-radius: 12rpx;
|
||
flex-shrink: 0;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.sk-body {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
}
|
||
}
|
||
|
||
.sk-row--article {
|
||
position: relative;
|
||
width: 500rpx;
|
||
height: 246rpx;
|
||
margin: 10rpx auto;
|
||
border-radius: 12rpx;
|
||
overflow: hidden;
|
||
|
||
.sk-cover {
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 12rpx;
|
||
}
|
||
|
||
.sk-cover-title {
|
||
position: absolute;
|
||
left: 0;
|
||
bottom: 0;
|
||
width: 100%;
|
||
height: 92rpx;
|
||
opacity: 0.5;
|
||
}
|
||
}
|
||
|
||
.sk-row--category {
|
||
width: 184rpx;
|
||
height: 100rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: #fff;
|
||
|
||
.sk-cate-item {
|
||
width: 100rpx;
|
||
height: 28rpx;
|
||
border-radius: 6rpx;
|
||
}
|
||
}
|
||
|
||
.list-skeleton--zone {
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
padding: 16rpx 24rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.sk-row--zone {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
width: 140rpx;
|
||
flex-shrink: 0;
|
||
margin-right: 16rpx;
|
||
|
||
.sk-zone-icon {
|
||
width: 88rpx;
|
||
height: 88rpx;
|
||
border-radius: 20rpx;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.sk-line--xs {
|
||
width: 72rpx;
|
||
}
|
||
}
|
||
|
||
.sk-line {
|
||
height: 24rpx;
|
||
border-radius: 6rpx;
|
||
margin-bottom: 16rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
|
||
.sk-line--lg {
|
||
width: 70%;
|
||
}
|
||
|
||
.sk-line--md {
|
||
width: 50%;
|
||
}
|
||
|
||
.sk-line--sm {
|
||
width: 90%;
|
||
}
|
||
|
||
.sk-line--xs {
|
||
width: 80rpx;
|
||
height: 20rpx;
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.sk-line-row .sk-line--md {
|
||
width: 40%;
|
||
margin-bottom: 0;
|
||
}
|
||
</style>
|