uniapp兼容h5和小程序等 骨架屏组件

skeleton.vue代码

<template>
	<view>
		<view class="skeleton" v-show="loading" :class="[animationClass]" v-for="skeleton in count">
			<view class="row" :style="{'flex-direction':direction}" >
				<view v-for="(item,index) in row" :key="item" class="row-item" :style="{'margin-right':mright}" >
					<view :style="{width:rowWidth,height:rowHeight,'border-radius':radius}"  v-if="variant === 'image'" :class="[varianttype]">
						<svg  viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
						    <path d="M64 896V128h896v768H64z m64-128l192-192 116.352 116.352L640 448l256 307.2V192H128v576z m224-480a96 96 0 1 1-0.064 192.064A96 96 0 0 1 352 288z"/>
						</svg>
					</view>
					<view v-else :class="[varianttype]" :style="{width:rowWidth,height:rowHeight}" class="row-class"></view>
				</view>
			</view>
		</view>
		<slot v-if="!loading"></slot>
	</view>
</template>
<script>
	export default {
		props: {
			//是否使用动画
			animate: {
				type: Boolean,
				default: false
			},
			//渲染多少个 template, 建议使用尽可能小的数字
			count: {
				type: Number,
				default: 1
			},
			//是否显示 skeleton 骨架屏
			loading: {
				type: Boolean,
				default: true
			},
			//骨架屏段落数量
			row: {
				type: Number,
				default: 1
			},
			//段落行宽度,默认为100%
			rowWidth:{
				type: String | Number,
				default: '100%'
			},
			//段落行高度
			rowHeight:{
				type: String | Number,
			},
			//圆角的边框
			radius:{
				type: String | Number
			},
			//调整主轴方向
			direction:{
				type: String,
				default: 'column'
			},
			//右侧外边距
			mright:{
				type: String | Number
			},
			//当前显示的占位元素的样式
			variant: {
				type: String,
				values: [
				      'circle',
				      'h1',
				      'h3',
				      'text',
				      'caption',
				      'p',
				      'image',
				      'button',
				],
				default: 'text'
			}
		},
		computed: {
			animationClass() {
				return [this.animate ? 'skeleton_animation' : '']
			},
			varianttype(){
				return [this.variant ? 'skeleton__'+this.variant : 'text']
			}
		},
		data() {
			return {
			}
		}
	}
</script>

<style lang="scss" scoped>
	/* 占位元素的样式 */
	$skeleton-h1-height: 20px;
	$skeleton-h3-height: 18px;
	$skeleton-caption-height: 12px;
	$skeleton-button-height:40px;
	$skeleton-button-width:64px;
	$skeleton-circle-width:36px;
	$skeleton-circle-height:36px;
	$skeleton-text-height:13px;
	$skeleton-p-height:13px;
	$skeleton-image-width:200px;
	$skeleton-image-height:200px;
	$skeleton-image-svg-width:22%;
	$skeleton-image-svg-height:22%;
	
	.skeleton {
		background-color: #fff;
	}
	.row{
		display: flex; 
	}
	.row-class {
		width: 100%;
		height: 16px;
		margin-top: 12px;
		display: flex;
	}
	.row-item{
		width: 100%;
	}
	.row-item:nth-last-child(1){
		margin-right: 0 !important;
	}
	.skeleton_animation .row-class,.skeleton__image {
		background: linear-gradient(
		90deg,#f2f2f2 25%,#e6e6e6 37%,#f2f2f2 63%);
		background-size: 400% 100%;
		animation: skeleton-loading 1.4s ease infinite;
	}

	@keyframes skeleton-loading{
		0%{
			background-position:100% 50%
		}
		to{
			background-position:0 50%
		}
	}
	.skeleton__h1 {
		height: $skeleton-h1-height;
	}
	.skeleton__h3 {
		height: $skeleton-h3-height;
	}
	.skeleton__caption {
	    height: $skeleton-caption-height;
	}
	.skeleton__button {
	    height: $skeleton-button-height;
		width: $skeleton-button-width;
		border-radius: 4px;
	}
	.skeleton__circle {
	    height: $skeleton-circle-height;
		width: $skeleton-circle-width;
		border-radius: 50%;
		line-height: $skeleton-circle-height;
	}
	.skeleton__text {
	    width: 100%;
	    height:  $skeleton-text-height;
	}
	.skeleton__p {
		flex-shrink: 0;
	    width: 100%;
	    height: $skeleton-p-height;
	}
	.skeleton__image {
		margin-right: 8px;
		width: $skeleton-image-width;
		height:$skeleton-image-height;
		background-color: #f2f2f2;
	    display: flex;
		align-items: center;
		justify-content: center;
		border-radius: 0;
	}
	.row-item:nth-last-child(1) .skeleton__image{
		margin-right: 0px;
	}
	.skeleton__image svg {
	    fill: #dcdde0;
	    width: $skeleton-image-svg-width;
	    height: $skeleton-image-svg-height;
	}
</style>

 ## skeleton 骨架屏 示例代码

# skeleton 骨架屏

在需要等待加载内容的位置设置一个骨架屏,用法同 [elementui Skeleton 骨架屏](https://element.eleme.io/#/zh-CN/component/skeleton)类似。

## 属性说明

|属性名|类型|默认值|说明|
| -- | -- | --|--|
| animate | Boolean | false | 是否使用动画 |
| count | Number | 1 | 渲染多少个 template, 建议使用尽可能小的数字 |
| loading | Boolean | false | 是否显示 skeleton 骨架屏 |
| row | Number | 1 | 骨架屏段落数量 |
| rowWidth | String/Number | 100% | 段落行宽度,默认为100% |
| rowHeight | String/Number |  | 段落行高度,无默认值 |
| radius | String/Number |  | 圆角的边框,无默认值 |
| direction | String |column | 调整主轴方向,默认值为 column |
| mright | String/Number |  | 右侧外边距,无默认值 |
| variant | String |text| 当前显示的占位元素的样式,可选值 p / text / h1 / h3 / caption / button / image / circle |

## 示例代码

```html
<template>
	<view>
		<view class="content">
			<skeleton :row="4" direction='row' rowWidth="80px" radius='50%' rowHeight="80px" :animate='true' :loading='loading' variant='image'>
				<view class="imagelist-1">
					<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
					<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
					<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
					<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
				</view>
			</skeleton>
			<br/>
			<skeleton :row="4" direction='row'  rowWidth="80px" rowHeight="80px" :animate='true' :loading='loading' variant='image'>
				<view class="imagelist-2">
					<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
					<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
					<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
					<image src='https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1548&q=80'></image>
				</view>
			</skeleton>
			<br/>
			<skeleton :row='3' direction='column'  rowWidth="100%" rowHeight="13px" :animate='true' :loading='loading' variant='p'>
				<view >
				 <p>测试新闻标题1号</p>
				 <p>测试新闻标题2号</p>
				 <p>测试新闻标题3号</p>
				</view>
			</skeleton>
			<br/>
			<skeleton rowWidth="80px"  direction='row'  radius='50%' rowHeight="80px" :animate='true' :loading='loading' variant='image'>
				<view >
					<image src='https://images.unsplash.com/photo-1543852786-1cf6624b9987?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80'></image>
				</view>
			</skeleton>
			
			<skeleton  :animate='true' :loading='loading' variant='h1'>
				<view >
					<h1>标题</h1>
				</view>
			</skeleton>
			<skeleton :row='2' mright='8px' direction='row' :animate='true' :loading='loading' variant='text'>
				<view >
					<text>描述</text>
				</view>
			</skeleton>
			<skeleton :row='3' mright='8px' direction='row' :animate='true' :loading='loading' variant='text'>
				<view >
					<text>描述</text>
				</view>
			</skeleton>
			<skeleton :row='4' mright='8px' direction='row' :animate='true' :loading='loading' variant='text'>
				<view >
					<text>描述</text>
				</view>
			</skeleton>
	</view>
	</view>
</template>

<script>
	import skeleton from '../../components/lidao-skeleton/skeleton.vue'
	export default {
		data() {
			return {
				loading: true // 是否显示骨架屏组件
			}
		},
		onLoad() {
			// 通过延时模拟向后端请求数据,调隐藏骨架屏
			setTimeout(() => {
				this.loading = false;
			}, 3000)
		},components:{
			skeleton,
		}
	}
</script>
<style>
page{
	padding: 12px;
}
image{
	width: 80px;
	height: 80px;
	margin-right: 8px;
}
.imagelist-1 image{
	border-radius: 50%;
}
.imagelist-1 image:nth-last-child(1){
	margin-right: 0;
}
.imagelist-2 image:nth-last-child(1){
	margin-right: 0;
}
</style>

```

## 效果图

![图片描述](https://doc.shiyanlou.com/courses/7763/1693782/69bc26eb1c98c9e71476def878a517b1-0)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值