123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- <template>
- <view v-if="visibleSync" :style="[customStyle]" :class="{ 'u-drawer-visible': showDrawer }" class="u-drawer">
- <u-mask :maskClickAble="maskCloseAble" :show="showDrawer && mask" @click="maskClick"></u-mask>
- <view class="u-drawer-content" @tap="modeCenterClose(mode)" :class="[
- safeAreaInsetBottom ? 'safe-area-inset-bottom' : '',
- 'u-drawer-' + mode,
- showDrawer ? 'u-drawer-content-visible' : '',
- zoom && mode == 'center' ? 'u-animation-zoom' : ''
- ]"
- @touchmove.stop.prevent @tap.stop.prevent :style="[style]">
- <view class="u-mode-center-box" @tap.stop.prevent @touchmove.stop.prevent v-if="mode == 'center'" :style="[centerStyle]">
- <slot />
- </view>
- <block v-else>
- <slot />
- </block>
- </view>
- </view>
- </template>
- <script>
-
- import uMask from './u-mask'
- export default {
- name: 'u-popup',
- props: {
-
- show: {
- type: Boolean,
- default: false
- },
-
- mode: {
- type: String,
- default: 'left'
- },
-
- mask: {
- type: Boolean,
- default: true
- },
-
-
- length: {
- type: [Number, String],
- default: 'auto'
- },
-
- zoom: {
- type: Boolean,
- default: true
- },
-
- safeAreaInsetBottom: {
- type: Boolean,
- default: false
- },
-
- maskCloseAble: {
- type: Boolean,
- default: true
- },
-
- customStyle: {
- type: Object,
- default () {
- return {};
- }
- },
- value: {
- type: Boolean,
- default: false
- },
-
-
- popup: {
- type: Boolean,
- default: true
- },
-
- borderRadius: {
- type: [Number, String],
- default: 0
- },
- zIndex: {
- type: [Number, String],
- default: '100'
- }
- },
- data() {
- return {
- visibleSync: false,
- showDrawer: false,
- timer: null,
- style1: {}
- };
- },
- computed: {
-
- style() {
- let style = {};
- let translate = '100%';
-
- let length = (/%$/.test(this.length) || this.length == 'auto') ? this.length : uni.upx2px(this.length) + 'px';
-
- if (this.mode == 'left' || this.mode == 'top') translate = length == 'auto' ? '-100%' : '-' + length;
- if (this.mode == 'left' || this.mode == 'right') {
- style = {
- width: length,
- height: '100%',
- transform: `translate3D(${translate},0px,0px)`
- };
- } else if (this.mode == 'top' || this.mode == 'bottom') {
- style = {
- width: '100%',
- height: length,
- transform: `translate3D(0px,${translate},0px)`
- };
- }
- style.zIndex = this.zIndex ? this.zIndex : this.$u.zIndex.popup;
-
- if (this.borderRadius) {
- switch (this.mode) {
- case 'left':
- style.borderRadius = `0 ${this.borderRadius}rpx ${this.borderRadius}rpx 0`;
- break;
- case 'top':
- style.borderRadius = `0 0 ${this.borderRadius}rpx ${this.borderRadius}rpx`;
- break;
- case 'right':
- style.borderRadius = `${this.borderRadius}rpx 0 0 ${this.borderRadius}rpx`;
- break;
- case 'bottom':
- style.borderRadius = `${this.borderRadius}rpx ${this.borderRadius}rpx 0 0`;
- break;
- default:
- ;
- }
-
- style.overflow = 'hidden';
- }
- return style;
- },
-
- centerStyle() {
- let style = {};
- let length = (/%$/.test(this.length) || this.length == 'auto') ? this.length : uni.upx2px(this.length) + 'px';
- style.width = length;
- style.zIndex = this.zIndex ? this.zIndex : this.$u.zIndex.popup;
- if (this.borderRadius) {
- style.borderRadius = `${this.borderRadius}rpx`;
-
- style.overflow = 'hidden';
- }
- return style;
- }
- },
- watch: {
- value(val) {
- if (val) {
- this.open();
- } else {
- this.close();
- }
- }
- },
- created() {
-
- this.visibleSync = this.value;
- setTimeout(() => {
- this.showDrawer = this.value;
- }, 30);
- },
- methods: {
-
- maskClick() {
- this.close();
- },
- close() {
- this.change('showDrawer', 'visibleSync', false);
- },
-
-
- modeCenterClose(mode) {
- if (mode != 'center' || !this.maskCloseAble) return;
- this.close();
- },
- open() {
- this.change('visibleSync', 'showDrawer', true);
- },
-
-
- change(param1, param2, status) {
-
- if (this.popup == true) this.$emit('input', status);
- this[param1] = status;
- if (this.timer) {
- clearTimeout(this.timer);
- }
- this.timer = setTimeout(
- () => {
- this[param2] = status;
- this.$emit(status ? 'open' : 'close');
- },
- status ? 30 : 300
- );
- }
- },
- components:{
- uMask
- }
- };
- </script>
- <style scoped lang="scss">
- .u-drawer {
-
- display: block;
-
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- overflow: hidden;
- z-index: 999;
- background-color: rgba(0, 0, 0, 0.4);
- }
- .u-drawer-content {
-
- display: block;
-
- position: absolute;
- z-index: 1003;
- transition: all 0.25s linear;
- }
- .u-drawer-left {
- top: 0;
- bottom: 0;
- left: 0;
- background-color: #ffffff;
- }
- .u-drawer-right {
- right: 0;
- top: 0;
- bottom: 0;
- background-color: #ffffff;
- }
- .u-drawer-top {
- top: 0;
- left: 0;
- right: 0;
- background-color: #ffffff;
- }
- .u-drawer-bottom {
- bottom: 0;
- left: 0;
- right: 0;
- background-color: #ffffff;
- }
- .u-drawer-center {
-
- display: flex;
- flex-direction: column;
-
- bottom: 0;
- left: 0;
- right: 0;
- top: 0;
- justify-content: center;
- align-items: center;
- opacity: 0;
- z-index: 99999;
- }
- .u-mode-center-box {
- min-width: 100rpx;
- min-height: 100rpx;
-
- display: block;
-
- position: relative;
- background-color: #ffffff;
- }
- .u-drawer-content-visible.u-drawer-center {
- transform: scale(1);
- opacity: 1;
- }
- .u-animation-zoom {
- transform: scale(1.15);
- }
- .u-drawer-content-visible {
- transform: translate3D(0px, 0px, 0px) !important;
- }
- .u-drawer-mask {
-
- display: block;
-
- opacity: 0;
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- background-color: rgba(0, 0, 0, 0.4);
- transition: opacity 0.25s;
- }
- .u-drawer-mask-visible {
-
- display: block;
-
- opacity: 1;
- }
- </style>
|