JM-MiniApp/components/i-skeleton/i-skeleton.vue

136 lines
3.1 KiB
Vue
Raw Permalink Normal View History

2023-10-08 21:21:21 +08:00
<template>
<view class="i-skeleton" :style="{width: 'calc(100% - '+ size +')', background: bgColor}">
<view class="body">
<slot></slot>
</view>
<view class="body" :style="{width: width, height: height}" v-if="rows">
<view class="item_row">
<view class="icon" v-if="icon"></view>
<view class="colunm" v-if="type==='column'" :style="{width: icon ? '75%' : '100%'}">
<view class="rows"
:style="{width: typeof rowsW === 'string' ? rowsW : rowsW[index], height: typeof rowsH === 'string' ? rowsH : rowsH[index] }"
v-for="(item,index) in rows" :key="index"></view>
</view>
<view class="row" v-else-if="type === 'row'">
<view class="rows"
:style="{width: typeof rowsW === 'string' ? rowsW : rowsW[index], height: typeof rowsH === 'string' ? rowsH : rowsH[index] }"
v-for="(item,index) in rows" :key="index"></view>
</view>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import { defineProps } from 'vue';
const props = defineProps({
type: {
type: String,
default: 'column'
},
size: {
type: String,
default: '64rpx'
},
rows: {
type: Number,
default: 0
},
bgColor: {
type: String,
default: '#FFFFFF'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300rpx'
},
icon: {
type: Boolean,
default: true
},
rowsW: {
type: [String, Array],
default: '300rpx'
},
rowsH: {
type: [String, Array],
default: '20rpx'
}
})
</script>
<style lang="scss" scoped>
.i-skeleton {
margin: 0 auto;
border-radius: 12rpx;
.body {
border-radius: 12rpx;
display: flex;
flex-direction: column;
.item_row {
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
padding: 0 24rpx;
.icon {
width: 120rpx;
height: 120rpx;
background-color: #E6E6F0;
border-radius: 8rpx;
margin-right: 24rpx;
animation-duration: 2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: ease-out;
background: linear-gradient(to right, #E6E6F0 8%, #dddddd 18%, #E6E6F0 33%);
background-size: 800rpx 104rpx;
}
.colunm {
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
.rows {
margin-right: 8rpx;
}
}
.rows {
border-radius: 4rpx;
margin-bottom: 8rpx;
animation-duration: 2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: ease-out;
background: linear-gradient(to right, #E6E6F0 8%, #dddddd 18%, #E6E6F0 33%);
background-size: 800rpx 100rpx;
}
}
}
@keyframes placeHolderShimmer {
0% {
background-position: -400rpx 0
}
100% {
background-position: 400rpx 0
}
}
}
</style>