154 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
		
		
			
		
	
	
			154 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
|  | <template> | |||
|  | 	<view @tap="backToTop" class="u-back-top" :class="['u-back-top--mode--' + mode]" :style="[{ | |||
|  | 		bottom: bottom + 'rpx', | |||
|  | 		right: right + 'rpx', | |||
|  | 		borderRadius: mode == 'circle' ? '10000rpx' : '8rpx', | |||
|  | 		zIndex: uZIndex, | |||
|  | 		opacity: opacity | |||
|  | 	}, customStyle]"> | |||
|  | 		<view class="u-back-top__content" v-if="!$slots.default && !$slots.$default"> | |||
|  | 			<u-icon @click="backToTop" :name="icon" :custom-style="iconStyle"></u-icon> | |||
|  | 			<view class="u-back-top__content__tips"> | |||
|  | 				{{tips}} | |||
|  | 			</view> | |||
|  | 		</view> | |||
|  | 		<slot v-else /> | |||
|  | 	</view> | |||
|  | </template> | |||
|  | 
 | |||
|  | <script> | |||
|  | 	export default { | |||
|  | 		name: 'u-back-top', | |||
|  | 		props: { | |||
|  | 			// 返回顶部的形状,circle-圆形,square-方形
 | |||
|  | 			mode: { | |||
|  | 				type: String, | |||
|  | 				default: 'circle' | |||
|  | 			}, | |||
|  | 			// 自定义图标
 | |||
|  | 			icon: { | |||
|  | 				type: String, | |||
|  | 				default: 'arrow-upward' | |||
|  | 			}, | |||
|  | 			// 提示文字
 | |||
|  | 			tips: { | |||
|  | 				type: String, | |||
|  | 				default: '' | |||
|  | 			}, | |||
|  | 			// 返回顶部滚动时间
 | |||
|  | 			duration: { | |||
|  | 				type: [Number, String], | |||
|  | 				default: 100 | |||
|  | 			}, | |||
|  | 			// 滚动距离
 | |||
|  | 			scrollTop: { | |||
|  | 				type: [Number, String], | |||
|  | 				default: 0 | |||
|  | 			}, | |||
|  | 			// 距离顶部多少距离显示,单位rpx
 | |||
|  | 			top: { | |||
|  | 				type: [Number, String], | |||
|  | 				default: 400 | |||
|  | 			}, | |||
|  | 			// 返回顶部按钮到底部的距离,单位rpx
 | |||
|  | 			bottom: { | |||
|  | 				type: [Number, String], | |||
|  | 				default: 200 | |||
|  | 			}, | |||
|  | 			// 返回顶部按钮到右边的距离,单位rpx
 | |||
|  | 			right: { | |||
|  | 				type: [Number, String], | |||
|  | 				default: 40 | |||
|  | 			}, | |||
|  | 			// 层级
 | |||
|  | 			zIndex: { | |||
|  | 				type: [Number, String], | |||
|  | 				default: '9' | |||
|  | 			}, | |||
|  | 			// 图标的样式,对象形式
 | |||
|  | 			iconStyle: { | |||
|  | 				type: Object, | |||
|  | 				default() { | |||
|  | 					return { | |||
|  | 						color: '#909399', | |||
|  | 						fontSize: '38rpx' | |||
|  | 					} | |||
|  | 				} | |||
|  | 			}, | |||
|  | 			// 整个组件的样式
 | |||
|  | 			customStyle: { | |||
|  | 				type: Object, | |||
|  | 				default() { | |||
|  | 					return {} | |||
|  | 				} | |||
|  | 			} | |||
|  | 		}, | |||
|  | 		watch: { | |||
|  | 			showBackTop(nVal, oVal) { | |||
|  | 				// 当组件的显示与隐藏状态发生跳变时,修改组件的层级和不透明度
 | |||
|  | 				// 让组件有显示和消失的动画效果,如果用v-if控制组件状态,将无设置动画效果
 | |||
|  | 				if(nVal) { | |||
|  | 					this.uZIndex = this.zIndex; | |||
|  | 					this.opacity = 1; | |||
|  | 				} else { | |||
|  | 					this.uZIndex = -1; | |||
|  | 					this.opacity = 0; | |||
|  | 				} | |||
|  | 			} | |||
|  | 		}, | |||
|  | 		computed: { | |||
|  | 			showBackTop() { | |||
|  | 				// 由于scrollTop为页面的滚动距离,默认为px单位,这里将用于传入的top(rpx)值
 | |||
|  | 				// 转为px用于比较,如果滚动条到顶的距离大于设定的距离,就显示返回顶部的按钮
 | |||
|  | 				return this.scrollTop > uni.upx2px(this.top); | |||
|  | 			}, | |||
|  | 		}, | |||
|  | 		data() { | |||
|  | 			return { | |||
|  | 				// 不透明度,为了让组件有一个显示和隐藏的过渡动画
 | |||
|  | 				opacity: 0, | |||
|  | 				// 组件的z-index值,隐藏时设置为-1,就会看不到
 | |||
|  | 				uZIndex: -1 | |||
|  | 			} | |||
|  | 		}, | |||
|  | 		methods: { | |||
|  | 			backToTop() { | |||
|  | 				uni.pageScrollTo({ | |||
|  | 					scrollTop: 0, | |||
|  | 					duration: this.duration | |||
|  | 				}); | |||
|  | 			} | |||
|  | 		} | |||
|  | 	} | |||
|  | </script> | |||
|  | 
 | |||
|  | <style lang="scss" scoped> | |||
|  | 	@import "../../libs/css/style.components.scss"; | |||
|  | 	 | |||
|  | 	.u-back-top { | |||
|  | 		width: 80rpx; | |||
|  | 		height: 80rpx; | |||
|  | 		position: fixed; | |||
|  | 		z-index: 9; | |||
|  | 		@include vue-flex; | |||
|  | 		flex-direction: column; | |||
|  | 		justify-content: center; | |||
|  | 		background-color: #E1E1E1; | |||
|  | 		color: $u-content-color; | |||
|  | 		align-items: center; | |||
|  | 		transition: opacity 0.4s; | |||
|  | 		 | |||
|  | 		&__content { | |||
|  | 			@include vue-flex; | |||
|  | 			flex-direction: column; | |||
|  | 			align-items: center; | |||
|  | 			 | |||
|  | 			&__tips { | |||
|  | 				font-size: 24rpx; | |||
|  | 				transform: scale(0.8); | |||
|  | 				line-height: 1; | |||
|  | 			} | |||
|  | 		} | |||
|  | 	} | |||
|  | </style> |