uniapp常用组件

1.页面滚动组件

<template>
	<view class="scroll_top_view">
		<scroll-view
			class="scroll_view"

			@scrolltolower="$emit('scrolltolower', $event)"
			@refresherrefresh="$emit('refresherrefresh', $event)"
			:refresher-enabled="refresherEnabled"
			:refresher-triggered="refresherTriggered"
			:refresher-background="refresherBackground"
			:refresher-default-style="refresherDefaultStyle"
			:scroll-with-animation="scrollWithAnimation"

			@scroll="onScroll"
			:scroll-top="setScrollTop"
			enable-back-to-top
			scroll-y>
			<slot></slot>
		</scroll-view>
		<view
			v-if="scrollTopVisible"
			class="top_btn"
			:style="btnStyle"
			@click="scrollTo(0)">
			<view class="img">
				<image src="@/static/images/image/top_btn.png" mode="aspectFill" />
			</view>
		</view>
	</view>
</template>

<script>
	/**
	 * 用于在滚动视图中添加 “返回顶部” 按钮
	 * 如需其他功能,可在此基础上进行扩展
	 */
	export default {
		data() {
			return {
				currentScrollTop: 0,
				setScrollTop: null,
			}
		},

		props: {
			/**
			 * 滚动多少距离后显示 “返回顶部” 按钮
			 * true: 保持显示
			 * false: 不显示
			 */
			showScrollTop: {
				type: [Boolean, Number, String],
				default: 50,
			},
			btnStyle: {
				type: [Object, Array, String],
				default: '',
			},

			scrollTop: {
				type: Number,
				default: 0,
			},
			refresherEnabled: {
				type: Boolean,
				default: false,
			},
			refresherTriggered: {
				type: Boolean,
				default: false,
			},
			refresherBackground: {
				type: String,
				default: '#fff',
			},
			refresherDefaultStyle: {
				type: String,
				default: 'black',
			},
			scrollWithAnimation: {
				type: Boolean,
				default: true,
			},
		},

		computed: {
			scrollTopVisible() {
				if (typeof this.showScrollTop === 'boolean') {
					return this.showScrollTop;
				}
				return this.currentScrollTop > parseFloat(this.showScrollTop);
			},
		},

		watch: {
			scrollTop(val) {
				this.scrollTo(val);
			},
		},

		methods: {
			scrollTo(value = 0) {
				this.setScrollTop = this.currentScrollTop;
				this.$nextTick(() => {
					this.setScrollTop = value;
				});
			},

			onScroll(e) {
				this.currentScrollTop = e.detail.scrollTop;
				this.$emit('scroll', e);
			},
		},
	}
</script>

<style lang="scss" scoped>
	.scroll_top_view {
		position: absolute;
		width: 100%;
		height: 100%;
	}

	.scroll_view {
		position: absolute;
		width: 100%;
		height: 100%;
		z-index: 1;
	}

	.top_btn {
		position: absolute;
		bottom: 180rpx;
		right: 32rpx;
		width: 88rpx;
		height: 88rpx;
		border-radius: 100%;
		z-index: 2;
		.img {
			position: absolute;
			left: -18%;
			top: -18%;
			width: 136%;
			height: 136%;
			pointer-events: none;
		}
		image {
			width: 100%;
			height: 100%;
		}
	}
</style>

2.通用自定义头部

<template>
	<view id="pageHeader"
		:style="{ '--status-height': statusBarHeight, '--title-height': headerTitleHeight }">
		<!-- 顶部文字 -->
		<view v-if="showTitle" class="page_header"
			:style="{ 'background': bgColor,'color': textColor,
				'border-top': `1px solid ${bgColor}`, 'line-height': `calc(${menuBtnInfo.height + menuBtnInfo.top + 1}px - ${statusBarHeight})`, 'animationDelay': '0.1s' }">
			<view v-if="showBack" class="cuIcon-back" @tap="handleReturn" />
			<view :style="showBack?'margin-left: 40rpx':''" class="title-line">{{title}}
			    <view class="btn">
			    		<slot name="btn"></slot>
			    </view>
			
			</view>
		
		</view>
		<view v-else class="page_header" :style="{ 'background': bgColor }" />
		<view class="'titleBlank'">
			<!-- 占位 -->
		</view>
	</view>
</template>

<script>
	export default {
		options: { styleIsolation: 'shared' },
		props: {
			title: {
				// 导航栏标题
				type: String,
				default: '柳工充换电站云平台'
			},
			showTitle: {
				type: Boolean,
				default: true,
			},
			showBack: {
				type: Boolean,
				default: false
			},
			bgColor: {
				type: String,
				default: '#002D72'
			},
			textColor: {
				type: String,
				default: '#fff'
			},
			useReturnFunc: {
				type: Boolean,
				default: true
			}
		},
		data() {
			return {
				value: '',
				statusBarHeight: this.StatusBar,
				headerTitleHeight: '40px',
				menuBtnInfo: {},
				blankPadding: '',
			}
		},
		watch: {
			searchValue: {
				immediate: true,
				handler(newVal) {
					this.value = newVal;
				}
			}
		},
		created() {
			const systemInfo = uni.getSystemInfoSync();
			this.menuBtnInfo = uni.getMenuButtonBoundingClientRect();
			this.statusBarHeight = this.StatusBar ? `${this.StatusBar}px` : `${systemInfo.statusBarHeight}px`;
			if(this.showTitle) this.headerTitleHeight = `${this.menuBtnInfo.bottom - this.menuBtnInfo.top + 12}px`;
		},
		methods: {
			handleReturn() {
				if(this.useReturnFunc) uni.navigateBack();
				else this.$emit('return');
			},
			getHeaderInfo() {
				let domHeight = Number(this.statusBarHeight.slice(0, -2));
				domHeight += this.showTitle ? this.menuBtnInfo.bottom - this.menuBtnInfo.top + 12 : 0;
				return {
					menuBtnInfo: this.menuBtnInfo,
					statusBarHeight: Number(this.statusBarHeight.slice(0, -2)),
					totalHeight: domHeight,
					uint: 'px'
				}
			}
		}
	}
</script>

<style lang="scss" scoped>
	$uni-primary: #002D72;
	/* 自定义头部相关 */
	$statusBarHeight: var(--status-height, 20px); // 头部状态栏高度
	$headerTitleHeight: var(--title-height, 40px);
	#pageHeader{
		z-index: 999;
	}
	.page_header{
		z-index: 999;
		position: fixed;
		width: 100vw;
	}
	.page_header{
		padding-left: 16px;
		font-size: 20px;
	  text-align: left;
		top: 0;
		left: 0;
		padding-top: $statusBarHeight;
		height: calc(var(--status-height, 20px) + var(--title-height, 40px));
		
		view{
			line-height: inherit;
		}
	}
	.page_header [class^="cuIcon-"] {
	    display: inline-block;
	}
	.page_header .cuIcon-back{
	    position: absolute;
	    left: 20rpx;
	    cursor: pointer;
	}
	.titleBlank{
		padding-top: calc(var(--status-height, 20px) + var(--title-height, 0px));
		// padding-top: calc(var(--title-height, 0px));
	}
	.title-line{
		display: flex;
	    align-items: center;
		justify-content: space-between;
		.btn{
			margin-right: 200rpx;
		}
	}
</style>

3.使用

<template>
	<view class="page">
		<scroll-top-view
			:refresher-triggered="refresherTriggered"
			@refresherrefresh="refreshPage"
			refresher-background="#008df7"
			refresher-default-style="white"
			refresher-enabled>
			<view class="wrapper">
				<view class="bg"></view>
				<pageHeader title="工作台" bgColor="transparent" />
				<view class="appli_wrapper">
					<TodayWarning ref="TodayWarning" />
					<EnterMachine ref="EnterMachine" />
					<MachineType ref="MachineType" />
					<RateBarStats ref="RateBarStats" />
					<OilStats ref="OilStats" />
					<CommonApplication ref="CommonApplication" />
				</view>
			</view>
		</scroll-top-view>
	</view>
</template>

<script>
	import CommonApplication from './components/CommonApplication.vue'
	import TodayWarning from './components/TodayWarning.vue'
	import EnterMachine from './components/EnterMachine.vue'
	import MachineType from './components/MachineType.vue'
	import RateBarStats from './components/RateBarStats.vue'
	import OilStats from './components/OilStats.vue'

	export default {
		components: {
			CommonApplication,
			TodayWarning,
			EnterMachine,
			MachineType,
			RateBarStats,
			OilStats,
		},

		data() {
			return {
				refresherTriggered: false,
			}
		},

		mounted() {
			this.init()
		},

		methods: {
			async init() {
				await this.$nextTick()
				this.$modal.loading('加载中...')
				await Promise.all([
					this.$refs.CommonApplication?.init?.(),
					this.$refs.TodayWarning?.init?.(),
					this.$refs.EnterMachine?.init?.(),
					this.$refs.MachineType?.init?.(),
					this.$refs.RateBarStats?.init?.(),
					this.$refs.OilStats?.init?.(),
				]).finally(() => {
					this.$modal.closeLoading()
				})
			},

			async refreshPage() {
				this.refresherTriggered = true
				await this.init().catch(() => { })
				this.refresherTriggered = false
			},
		}
	}
</script>

<style lang="scss" scoped>
	.page {
		position: relative;
		height: 100vh;
		background-color: #f2f7ff;
	}

	.bg {
		position: absolute;
		top: 0;
		width: 100%;
		height: 450rpx;
		background: linear-gradient(180deg, #008df7 0, #f2f7ff 450rpx);
	}

	.wrapper {
		padding-bottom: calc(100rpx + env(safe-area-inset-bottom) / 2);
		box-sizing: border-box;
		/deep/ .page_header {
			position: absolute !important;
		}
	}

	.appli_wrapper {
		flex: 1;
		margin-top: 10rpx;
		padding-bottom: 32rpx;
	}
</style>

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值