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”;
}