You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
271 lines
4.7 KiB
271 lines
4.7 KiB
2 years ago
|
<template>
|
||
|
<view>
|
||
|
<view v-if="loading" class="skeleton" :class="{ animate: animate,margin16:!isClassify }" :style="{ justifyContent: flexType}">
|
||
|
<!-- 轮播图 -->
|
||
|
<view
|
||
|
v-if="imgTitle"
|
||
|
class="skeleton-imgTitle"
|
||
|
style="width: 95%;border-radius: 10px;height: 100px;display: block;"
|
||
|
></view>
|
||
|
<!-- 头像图 -->
|
||
|
<view
|
||
|
v-if="showAvatar && !imgTitle"
|
||
|
class="skeleton-avatar"
|
||
|
v-for="(item, index) in nameRow"
|
||
|
:key="index"
|
||
|
:class="[avatarShape]"
|
||
|
:style="{ width: avatarSize, height: avatarSize}"
|
||
|
></view>
|
||
|
<!-- 文字条 -->
|
||
|
<view class="skeleton-content" v-if="showTitle && !imgTitle">
|
||
|
<view class="skeleton-title" :style="{ width: titleWidth }"></view>
|
||
|
<view class="skeleton-rows">
|
||
|
<view
|
||
|
class="skeleton-row-item"
|
||
|
v-for="(item, index) in rowList"
|
||
|
:key="index"
|
||
|
:style="{ width: item.width }"
|
||
|
></view>
|
||
|
</view>
|
||
|
</view>
|
||
|
|
||
|
<view v-if="isClassify"
|
||
|
class="classify-avatar"
|
||
|
>
|
||
|
<view class="top dis-flex">
|
||
|
<view class="top-con" v-for="(item,index) in [1,2,3,4,5,6,7,8,9]" :key="index">
|
||
|
<view class="img">
|
||
|
|
||
|
</view>
|
||
|
<view class="title"></view>
|
||
|
</view>
|
||
|
|
||
|
</view>
|
||
|
<view class="dis-flex boto">
|
||
|
<view class="left">
|
||
|
|
||
|
</view>
|
||
|
<view class="right flex-1 dis-flex">
|
||
|
|
||
|
<view class="ri-top">
|
||
|
|
||
|
</view>
|
||
|
<view class="dis-flex ri-item">
|
||
|
<view class="skeleton-avatar "></view>
|
||
|
<view class="skeleton-rows">
|
||
|
<view
|
||
|
class="skeleton-row-item"
|
||
|
v-for="(item, index) in rowList"
|
||
|
:key="index"
|
||
|
:style="{ width: item.width }"
|
||
|
>
|
||
|
</view>
|
||
|
</view>
|
||
|
</view>
|
||
|
|
||
|
</view>
|
||
|
</view>
|
||
|
</view>
|
||
|
|
||
|
</view>
|
||
|
<view v-else><slot></slot></view>
|
||
|
</view>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
const DEFAULT_ROW_WIDTH = '100%'
|
||
|
const DEFAULT_LAST_ROW_WIDTH = '80%'
|
||
|
|
||
|
export default {
|
||
|
props: {
|
||
|
loading: {
|
||
|
type: Boolean,
|
||
|
default: true,
|
||
|
},
|
||
|
isClassify:{
|
||
|
type: Boolean,
|
||
|
default: false,
|
||
|
},
|
||
|
imgTitle: {
|
||
|
type: Boolean,
|
||
|
default: false,
|
||
|
},
|
||
|
nameRow:{
|
||
|
type: Number,
|
||
|
default: 1,
|
||
|
},
|
||
|
flexType:{
|
||
|
type: String,
|
||
|
default: 'flex-start', // center 居中 √ space-between 两端对齐 √ space-around 子元素拉手分布 √ flex-start 居左 flex-end 居右
|
||
|
},
|
||
|
showAvatar: {
|
||
|
type: Boolean,
|
||
|
default: true,
|
||
|
},
|
||
|
avatarSize: {
|
||
|
type: String,
|
||
|
default: '50px',
|
||
|
},
|
||
|
avatarShape: {
|
||
|
type: String,
|
||
|
default: 'round', // square | round
|
||
|
},
|
||
|
showTitle: {
|
||
|
type: Boolean,
|
||
|
default: false,
|
||
|
},
|
||
|
titleWidth: {
|
||
|
type: String,
|
||
|
default: '40%',
|
||
|
},
|
||
|
row: {
|
||
|
type: Number,
|
||
|
default: 3,
|
||
|
},
|
||
|
animate: {
|
||
|
type: Boolean,
|
||
|
default: true,
|
||
|
},
|
||
|
},
|
||
|
data() {
|
||
|
return {}
|
||
|
},
|
||
|
computed: {
|
||
|
rowList() {
|
||
|
let list = []
|
||
|
for (let i = 0; i < this.row; i++) {
|
||
|
list.push({
|
||
|
width: i === this.row - 1 && i !== 0 ? DEFAULT_LAST_ROW_WIDTH : DEFAULT_ROW_WIDTH,
|
||
|
|
||
|
})
|
||
|
}
|
||
|
return list
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
<style lang="scss" scoped>
|
||
|
|
||
|
.classify-avatar{
|
||
|
height: calc(100vh - 60px);
|
||
|
}
|
||
|
.boto{
|
||
|
height: calc(100% - 150rpx);
|
||
|
}
|
||
|
.top{
|
||
|
height: 150rpx;
|
||
|
overflow: hidden;
|
||
|
.top-con{
|
||
|
height: 100%;
|
||
|
padding: 0 15rpx;
|
||
|
text-align: center;
|
||
|
|
||
|
}
|
||
|
.img{
|
||
|
width: 80rpx;
|
||
|
height: 80rpx;
|
||
|
padding: 2rpx;
|
||
|
margin: 0 0 10rpx;
|
||
|
background:var(--bg-color);
|
||
|
border-radius: 50% !important;
|
||
|
}
|
||
|
.title{
|
||
|
height: 16px;
|
||
|
width: 80rpx;
|
||
|
border-radius: 8px;
|
||
|
background:var(--bg-color) ;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
.left{
|
||
|
width: 200rpx;
|
||
|
height: 100%;
|
||
|
background:var(--bg-color) ;
|
||
|
box-sizing: border-box;
|
||
|
margin: 0 20rpx;
|
||
|
border-radius: 8px;
|
||
|
}
|
||
|
.right{
|
||
|
|
||
|
padding: 16px;
|
||
|
height: 100%;
|
||
|
|
||
|
.ri-top{
|
||
|
|
||
|
}
|
||
|
.ri-item{
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
/* */
|
||
|
.skeleton {
|
||
|
display: flex;
|
||
|
|
||
|
--bg-color: #f2f3f5;
|
||
|
--row-height: 16px;
|
||
|
--row-margin-top: 16px;
|
||
|
}
|
||
|
|
||
|
.margin16{
|
||
|
margin: 16px 16px 0 16px;
|
||
|
}
|
||
|
|
||
|
.skeleton-imgTitle {
|
||
|
flex-wrap: wrap;
|
||
|
background: var(--bg-color);
|
||
|
margin: 10px auto;
|
||
|
|
||
|
}
|
||
|
.skeleton-avatar {
|
||
|
flex-shrink: 0;
|
||
|
background: var(--bg-color);
|
||
|
margin-right: 8px;
|
||
|
}
|
||
|
.skeleton-avatar.round {
|
||
|
border-radius: 50%;
|
||
|
}
|
||
|
|
||
|
.skeleton-content {
|
||
|
width: 100%;
|
||
|
}
|
||
|
|
||
|
.skeleton-title {
|
||
|
background-color: var(--bg-color);
|
||
|
height: var(--row-height);
|
||
|
}
|
||
|
|
||
|
.skeleton-title + .skeleton-rows {
|
||
|
margin-top: var(--row-margin-top);
|
||
|
}
|
||
|
|
||
|
.skeleton-rows {
|
||
|
}
|
||
|
|
||
|
.skeleton-row-item {
|
||
|
background-color: var(--bg-color);
|
||
|
height: var(--row-height);
|
||
|
}
|
||
|
.skeleton-row-item:not(:first-child) {
|
||
|
margin-top: var(--row-margin-top);
|
||
|
}
|
||
|
|
||
|
.skeleton.animate {
|
||
|
animation: skeleton-blink 1.2s ease-in-out infinite;
|
||
|
}
|
||
|
|
||
|
@keyframes skeleton-blink {
|
||
|
0% {
|
||
|
opacity: 1;
|
||
|
}
|
||
|
50% {
|
||
|
opacity: 0.6;
|
||
|
}
|
||
|
100% {
|
||
|
opacity: 1;
|
||
|
}
|
||
|
}
|
||
|
</style>
|