对uniapp弹窗封装

1.新建文件wyb-popup在里面创建wyb-popup.vue和iconfont.css

<template>
	<view v-if="isShow">
		<view
			@tap.stop.prevent
			@touchmove.stop.prevent
			class="wyb-popup-box"
			:style="{
				transitionDuration: duration + 'ms',
				opacity: contentOpacity || (type === 'center' ? 0 : 1),
				transform: contentTransform || autoTransform,
				zIndex: zIndex,
				borderTopRightRadius: type === 'center' || type === 'bottom' || type === 'left' ? radius + 'px' : 0,
				borderTopLeftRadius: type === 'center' || type === 'bottom' || type === 'right' ? radius + 'px' : 0,
				borderBottomRightRadius: type === 'center' || type === 'top' || type === 'left' ? radius + 'px' : 0,
				borderBottomLeftRadius: type === 'center' || type === 'top' || type === 'right' ? radius + 'px' : 0,
				width: autoWidth,
				height: autoHeight,
				minWidth: width + 'rpx',
				minHeight: height + 'rpx',
				top: sizeChange && type === 'center' ? winReTop : autoTop,
				bottom: autoBottom,
				left: autoLeft,
				right: autoRight,
				backgroundColor: bgColor
			}"
		>
			<view class="wyb-popup-header" v-if="showHeader"><image class="wyb-popup-custom-header" v-if="showHeader" :src="showHeaderImage" /></view>
			<view class="line"></view>
			<view class="wyb-popup-close" v-if="showCloseIcon">
				<image class="wyb-popup-custom-close" v-if="showCloseIcon && closeIcon" :src="closeIcon" @tap="hide" style="width: 58upx;height: 58upx;" />
				<view v-if="showCloseIcon && !closeIcon" class="iconfont icon-close" @tap="hide" />
			</view>

			<scroll-view
				class="wyb-popup-container"
				:style="{
					width: autoWidth,
					height: autoHeight
				}"
				:enable-flex="true"
				:scroll-y="scrollY"
				:scroll-x="scrollX"
			>
				<view class="wyb-popup-slot"><slot></slot></view>
			</scroll-view>
		</view>
		<view
			class="wyb-popup-mask"
			@tap.stop="close"
			@touchmove.stop.prevent
			:style="{
				opacity: maskOpacity,
				transitionDuration: duration + 'ms',
				backgroundColor: 'rgba(0, 0, 0, ' + maskAlpha + ')',
				zIndex: zIndex - 1
			}"
		/>
	</view>
</template>

<script>
export default {
	data() {
		return {
			w: uni.getSystemInfoSync().screenWidth,
			h: uni.getSystemInfoSync().screenHeight,
			isShow: false,
			winReBottom: '',
			winReTop: '',
			sizeChange: false,
			contentOpacity: null,
			contentTransform: null,
			maskOpacity: 0
		};
	},
	computed: {
		autoCenterTop() {
			let statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
			let windowHeight = uni.getSystemInfoSync().windowHeight;
			let popupHeight = this.rpxToPx(this.height);
			let navHeight = 44;
			let result = `${(windowHeight - popupHeight) / 2 - this.negativeTop}px`;
			return result;
		},
		autoTransform() {
			let result = '';
			switch (this.type) {
				case 'center':
					if (this.centerAnim === 'zoom-lessen') {
						result = `scale(${this.zoomLessenMulti})`;
					} else if (this.centerAnim === 'slide-up') {
						result = `translateY(${100 * this.slideMulti}%)`;
					} else if (this.centerAnim === 'slide-down') {
						result = `translateY(${-100 * this.slideMulti}%)`;
					} else if (this.centerAnim === 'fade') {
						result = 'auto';
					}
					break;
				case 'bottom':
					result = 'translateY(100%)';
					break;
				case 'top':
					result = 'translateY(-100%)';
					break;
				case 'left':
					result = 'translateX(-100%)';
					break;
				case 'right':
					result = 'translateX(100%)';
					break;
			}
			return result;
		},
		autoWidth() {
			if (this.type === 'center') {
				return `${this.width}rpx`;
			} else {
				if (this.mode === 'size-fixed') {
					if (this.type === 'top' || this.type === 'bottom') {
						return '100%';
					} else {
						return `${this.width}rpx`;
					}
				} else {
					if (this.type === 'top' || this.type === 'bottom') {
						return '100%';
					} else {
						return 'auto';
					}
				}
			}
		},
		autoHeight() {
			if (this.type === 'center') {
				return `${this.height}rpx`;
			} else {
				if (this.mode === 'size-fixed') {
					if (this.type === 'left' || this.type === 'right') {
						return '100%';
					} else {
						return `${this.height}rpx`;
					}
				} else {
					if (this.type === 'left' || this.type === 'right') {
						return '100%';
					} else {
						return 'auto';
					}
				}
			}
		},
		autoTop() {
			if (this.type === 'center') {
				return this.autoCenterTop;
			} else if (this.type === 'bottom') {
				return 'auto';
			} else {
				return 0;
			}
		},
		autoBottom() {
			if (this.type === 'center' || this.type === 'top') {
				return 'auto';
			} else {
				return 0;
			}
		},
		autoLeft() {
			if (this.type === 'center') {
				return `${(this.w - this.rpxToPx(this.width)) / 2}px`;
			} else if (this.type === 'right') {
				return 'auto';
			} else {
				return 0;
			}
		},
		autoRight() {
			if (this.type === 'center' || this.type === 'left') {
				return 'auto';
			} else {
				return 0;
			}
		}
	},
	props: {
		type: {
			type: String,
			default: 'bottom'
		},
		mode: {
			type: String,
			default: 'size-auto'
		},
		height: {
			type: [String, Number],
			default: 500
		},
		width: {
			type: [String, Number],
			default: 500
		},
		radius: {
			type: [String, Number],
			default: 0
		},
		zIndex: {
			type: [String, Number],
			default: 10076
		},
		maskClickClose: {
			type: Boolean,
			default: true
		},
		maskAlpha: {
			type: Number,
			default: 0.8
		},
		duration: {
			type: Number,
			default: 400
		},
		showCloseIcon: {
			type: Boolean,
			default: false
		},
		showHeader: {
			type: Boolean,
			default: false
		},
		scrollY: {
			type: Boolean,
			default: false
		},
		scrollX: {
			type: Boolean,
			default: false
		},
		closeIconPos: {
			type: String,
			default: 'top-right'
		},
		closeIcon: {
			type: String,
			default: '../../static/popup/close-rule.png'
		},
		closeIconSize: {
			type: [String, Number],
			default: '20'
		},
		vertOffset: {
			type: [String, Number],
			default: '22'
		},
		horiOffset: {
			type: [String, Number],
			default: '22'
		},
		centerAnim: {
			type: String,
			default: 'zoom-lessen'
		},
		bgColor: {
			type: String,
			default: '#ffffff'
		},
		zoomLessenMulti: {
			type: Number,
			default: 1.15
		},
		slideMulti: {
			type: Number,
			default: 1
		},
		negativeTop: {
			type: Number,
			default: 0
		},
		showHeaderImage: {
			type: String,
			default: ''
		}
	},
	mounted() {
		// #ifdef H5
		let winHeight = uni.getSystemInfoSync().windowHeight;
		uni.onWindowResize(res => {
			this.sizeChange = true;
			if (this.type === 'bottom') {
				this.winReBottom = winHeight - res.size.windowHeight + 'px';
			} else if (this.type === 'center') {
				this.winReTop = (res.size.windowHeight - this.rpxToPx(this.height)) / 2 - this.negativeTop + 'px';
			}
		});
		// #endif
	},
	methods: {
		close() {
			this.maskClickClose && this.hide();
		},
		show() {
			this.isShow = true;
			// #ifndef H5
			this.$nextTick(() => {
				this.maskIn();
				this.contentIn();
				this.wait(this.duration + 1).then(() => {
					this.$emit('show', {
						pageScroll: false,
						overflow: 'hidden'
					});
				});
			});
			// #endif
			// #ifdef H5
			this.wait(10).then(() => {
				this.maskIn();
				this.contentIn();
				this.wait(this.duration + 1).then(() => {
					this.$emit('show', {
						pageScroll: false,
						overflow: 'hidden'
					});
				});
			});
			// #endif
		},
		hide() {
			this.contentOut();
			this.maskOut();
			this.wait(this.duration + 1).then(() => {
				this.isShow = false;
				this.$emit('hide', {
					pageScroll: true,
					overflow: 'scroll'
				});
			});
		},
		contentIn() {
			switch (this.type) {
				case 'center':
					if (this.centerAnim === 'zoom-lessen') {
						this.contentOpacity = 1;
						this.contentTransform = 'scale(1)';
					} else if (this.centerAnim === 'slide-up' || this.centerAnim === 'slide-down') {
						this.contentOpacity = 1;
						this.contentTransform = 'translateY(0)';
					} else if (this.centerAnim === 'fade') {
						this.contentOpacity = 1;
					}
					break;
				case 'bottom':
				case 'top':
					this.contentTransform = 'translateY(0)';
					break;
				case 'left':
				case 'right':
					this.contentTransform = 'translateX(0)';
					break;
			}
		},
		contentOut() {
			this.contentOpacity = null;
			this.contentTransform = null;
		},
		maskIn() {
			this.maskOpacity = 1;
		},
		maskOut() {
			this.maskOpacity = 0;
		},
		rpxToPx(rpx) {
			return (rpx / 750) * this.w;
		},
		wait(time) {
			return new Promise(resolve => {
				setTimeout(() => {
					resolve();
				}, time);
			});
		}
	}
};
</script>

<style>
@import './iconfont.css';
.wyb-popup-header {
	position: absolute;
	height: 110rpx;
	width: 100%;
	/* background-color: red; */
	z-index: 20000;
	top: -80rpx;
	text-align: center;
}
.wyb-popup-header .wyb-popup-custom-header {
	width: 287rpx;
	height: 100%;
}
.line {
	width: 2upx;
	height: 0upx;
	background-color: #8e8987;
	position: absolute;
	bottom: -80upx;
	left: 250upx;
}

.wyb-popup-box {
	width: 500upx;
	height: auto;
	position: fixed;
	transition-timing-function: ease-out;
	transition-property: opacity, transform;
}

.wyb-popup-container {
	position: relative;
	box-sizing: border-box;
}

.wyb-popup-slot {
	width: 100%;
	height: 100%;
}

.wyb-popup-mask {
	position: fixed;
	top: 0;
	left: 0;
	bottom: 0;
	right: 0;
	transition-timing-function: ease;
	transition-property: opacity, transform;
}

.wyb-popup-close {
	position: absolute;
	font-size: 40rpx;
	color: #808080;
	z-index: 20000;
	bottom: -80upx !important;
	left: 47% !important;
}

.wyb-popup-custom-close {
	left: 0;
	top: 0;
	position: absolute;
}
</style>

3.iconfont.css代码在这里插入代码片@font-face {font-family: “iconfont”;
src: url(‘data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAKUAAsAAAAABlAAAAJJAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcApcdgE2AiQDCAsGAAQgBYRtBy8bmwXIrjBu4UkbIjvjLimCmu1EP9KHAd4jgmi/3+zde18toRbpnkUTzRKRUkgQE6RA9xL+tMuG6RYp8bFsgmbcecAB9mDhH67tDS3pQsIsmSbPL7chM1RKsFr5mNDBoUDPJItlaZG8fvhi/tciWcbRfJ7L6U2gA1l9oBz3orEmTRpAvTigAPfCKLISSiNtGLvAJdwn0DCHgMfN/kgLK1jLAvE0p7YWzoUVCparCZWavYV4U6qllxTNa/j5+JeKMEmZWQ1njw1PK39hF+TnFG59QoSADpfI2AEUxFVt+oQpGIc10pYlYF+1wRfTfZfYq12wv86qboEZqLgnpau61VyC21L06V8d9cuJmT795hWPJp8ayHj0wrZNx+/+1Nzdf8MBtu9H2p+tgB5tn/W1PEZvgeD5Xf/if61ZgE9foa3Qz0ttd57gtyh79hS62nKmQlXWDiczp2tqaGAK+we+sZbxPeRDzXiEt2o2RVazQhbsDkpNu6io2UPDNn24aagxRVHHlgkQehaSjg9kPYcs2IvSxENFL0w03ASd2bQW82is0d6iB+YE2ZWCOO5tNKodIN0xe51Vh/wE15t5DGQsUcy1UOB6jg19T1NjSyCsJQcFHkPGJJS1XKC7jaXtVpV4nNS9KGYl16KOrCHbFvIA4wRkLkkg/uitaOn9A4jaYWzrlq6a/ARa25hPDiRG9CBbBtGr616e6faolGGLAMGaxAEFZiGGkUCpn7WAXFsxaURSKeH2oNDXEFvfxL/uGDRY1hT2lKy8Y3KDmgYA’) format(‘woff2’)
}

.iconfont {
font-family: “iconfont” !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.icon-close:before {
content: “\e622”;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值