From d1448cb0ef10f358bb7bddb4e1ec268515e0b787 Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期二, 15 七月 2025 11:46:57 +0800 Subject: [PATCH] 项目初始化 --- uni_modules/uview-ui/components/u-popup/u-popup.vue | 304 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 304 insertions(+), 0 deletions(-) diff --git a/uni_modules/uview-ui/components/u-popup/u-popup.vue b/uni_modules/uview-ui/components/u-popup/u-popup.vue new file mode 100644 index 0000000..2ca51cc --- /dev/null +++ b/uni_modules/uview-ui/components/u-popup/u-popup.vue @@ -0,0 +1,304 @@ +<template> + <view class="u-popup"> + <u-overlay + :show="show" + @click="overlayClick" + v-if="overlay" + :duration="overlayDuration" + :customStyle="overlayStyle" + :opacity="overlayOpacity" + ></u-overlay> + <u-transition + :show="show" + :customStyle="transitionStyle" + :mode="position" + :duration="duration" + @afterEnter="afterEnter" + @click="clickHandler" + > + <view + class="u-popup__content" + :style="[contentStyle]" + @tap.stop="noop" + > + <u-status-bar v-if="safeAreaInsetTop"></u-status-bar> + <slot></slot> + <view + v-if="closeable" + @tap.stop="close" + class="u-popup__content__close" + :class="['u-popup__content__close--' + closeIconPos]" + hover-class="u-popup__content__close--hover" + hover-stay-time="150" + > + <u-icon + name="close" + color="#909399" + size="18" + bold + ></u-icon> + </view> + <u-safe-bottom v-if="safeAreaInsetBottom"></u-safe-bottom> + </view> + </u-transition> + </view> +</template> + +<script> + import props from './props.js'; + + /** + * popup 寮圭獥 + * @description 寮瑰嚭灞傚鍣紝鐢ㄤ簬灞曠ず寮圭獥銆佷俊鎭彁绀虹瓑鍐呭锛屾敮鎸佷笂銆佷笅銆佸乏銆佸彸鍜屼腑閮ㄥ脊鍑恒�傜粍浠跺彧鎻愪緵瀹瑰櫒锛屽唴閮ㄥ唴瀹圭敱鐢ㄦ埛鑷畾涔� + * @tutorial https://www.uviewui.com/components/popup.html + * @property {Boolean} show 鏄惁灞曠ず寮圭獥 (榛樿 false ) + * @property {Boolean} overlay 鏄惁鏄剧ず閬僵 锛堥粯璁� true 锛� + * @property {String} mode 寮瑰嚭鏂瑰悜锛堥粯璁� 'bottom' 锛� + * @property {String | Number} duration 鍔ㄧ敾鏃堕暱锛屽崟浣峬s 锛堥粯璁� 300 锛� + * @property {String | Number} overlayDuration 閬僵灞傚姩鐢绘椂闀匡紝鍗曚綅ms 锛堥粯璁� 350 锛� + * @property {Boolean} closeable 鏄惁鏄剧ず鍏抽棴鍥炬爣锛堥粯璁� false 锛� + * @property {Object | String} overlayStyle 鑷畾涔夐伄缃╃殑鏍峰紡 + * @property {String | Number} overlayOpacity 閬僵閫忔槑搴︼紝0-1涔嬮棿锛堥粯璁� 0.5锛� + * @property {Boolean} closeOnClickOverlay 鐐瑰嚮閬僵鏄惁鍏抽棴寮圭獥 锛堥粯璁� true 锛� + * @property {String | Number} zIndex 灞傜骇 锛堥粯璁� 10075 锛� + * @property {Boolean} safeAreaInsetBottom 鏄惁涓篿PhoneX鐣欏嚭搴曢儴瀹夊叏璺濈 锛堥粯璁� true 锛� + * @property {Boolean} safeAreaInsetTop 鏄惁鐣欏嚭椤堕儴瀹夊叏璺濈锛堢姸鎬佹爮楂樺害锛� 锛堥粯璁� false 锛� + * @property {String} closeIconPos 鑷畾涔夊叧闂浘鏍囦綅缃紙榛樿 'top-right' 锛� + * @property {String | Number} round 鍦嗚鍊硷紙榛樿 0锛� + * @property {Boolean} zoom 褰搈ode=center鏃� 鏄惁寮�鍚缉鏀撅紙榛樿 true 锛� + * @property {Object} customStyle 缁勪欢鐨勬牱寮忥紝瀵硅薄褰㈠紡 + * @event {Function} open 寮瑰嚭灞傛墦寮� + * @event {Function} close 寮瑰嚭灞傛敹璧� + * @example <u-popup v-model="show"><text>鍑烘筏娉ヨ�屼笉鏌擄紝婵竻娑熻�屼笉濡�</text></u-popup> + */ + export default { + name: 'u-popup', + mixins: [uni.$u.mpMixin, uni.$u.mixin, props], + data() { + return { + overlayDuration: this.duration + 50 + } + }, + watch: { + show(newValue, oldValue) { + if (newValue === true) { + // #ifdef MP-WEIXIN + const children = this.$children + this.retryComputedComponentRect(children) + // #endif + } + } + }, + computed: { + transitionStyle() { + const style = { + zIndex: this.zIndex, + position: 'fixed', + display: 'flex', + } + style[this.mode] = 0 + if (this.mode === 'left') { + return uni.$u.deepMerge(style, { + bottom: 0, + top: 0, + }) + } else if (this.mode === 'right') { + return uni.$u.deepMerge(style, { + bottom: 0, + top: 0, + }) + } else if (this.mode === 'top') { + return uni.$u.deepMerge(style, { + left: 0, + right: 0 + }) + } else if (this.mode === 'bottom') { + return uni.$u.deepMerge(style, { + left: 0, + right: 0, + }) + } else if (this.mode === 'center') { + return uni.$u.deepMerge(style, { + alignItems: 'center', + 'justify-content': 'center', + top: 0, + left: 0, + right: 0, + bottom: 0 + }) + } + }, + contentStyle() { + const style = {} + // 閫氳繃璁惧淇℃伅鐨剆afeAreaInsets鍊兼潵鍒ゆ柇鏄惁闇�瑕侀鐣欓《閮ㄧ姸鎬佹爮鍜屽簳閮ㄥ畨鍏ㄥ眬鐨勪綅缃� + // 涓嶄娇鐢╟ss鏂规锛屾槸鍥犱负nvue涓嶆敮鎸乧ss鐨刬PhoneX瀹夊叏鍖烘煡璇㈠睘鎬� + const { + safeAreaInsets + } = uni.$u.sys() + if (this.mode !== 'center') { + style.flex = 1 + } + // 鑳屾櫙鑹诧紝涓�鑸敤浜庤缃负transparent锛屽幓闄ら粯璁ょ殑鐧借壊鑳屾櫙 + if (this.bgColor) { + style.backgroundColor = this.bgColor + } + if(this.round) { + const value = uni.$u.addUnit(this.round) + if(this.mode === 'top') { + style.borderBottomLeftRadius = value + style.borderBottomRightRadius = value + } else if(this.mode === 'bottom') { + style.borderTopLeftRadius = value + style.borderTopRightRadius = value + } else if(this.mode === 'center') { + style.borderRadius = value + } + } + return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle)) + }, + position() { + if (this.mode === 'center') { + return this.zoom ? 'fade-zoom' : 'fade' + } + if (this.mode === 'left') { + return 'slide-left' + } + if (this.mode === 'right') { + return 'slide-right' + } + if (this.mode === 'bottom') { + return 'slide-up' + } + if (this.mode === 'top') { + return 'slide-down' + } + }, + }, + methods: { + // 鐐瑰嚮閬僵 + overlayClick() { + if (this.closeOnClickOverlay) { + this.$emit('close') + } + }, + close(e) { + this.$emit('close') + }, + afterEnter() { + this.$emit('open') + }, + clickHandler() { + // 鐢变簬涓儴寮瑰嚭鏃讹紝鍏秛-transition鍗犳嵁浜嗘暣涓〉闈㈢浉褰撲簬閬僵锛屾鏃堕渶瑕佸彂鍑洪伄缃╃偣鍑讳簨浠讹紝鏄惁鏃犳硶閫氳繃鐐瑰嚮閬僵鍏抽棴寮圭獥 + if(this.mode === 'center') { + this.overlayClick() + } + this.$emit('click') + }, + // #ifdef MP-WEIXIN + retryComputedComponentRect(children) { + // 缁勪欢鍐呴儴闇�瑕佽绠楄妭鐐圭殑缁勪欢 + const names = ['u-calendar-month', 'u-album', 'u-collapse-item', 'u-dropdown', 'u-index-item', 'u-index-list', + 'u-line-progress', 'u-list-item', 'u-rate', 'u-read-more', 'u-row', 'u-row-notice', 'u-scroll-list', + 'u-skeleton', 'u-slider', 'u-steps-item', 'u-sticky', 'u-subsection', 'u-swipe-action-item', 'u-tabbar', + 'u-tabs', 'u-tooltip' + ] + // 鍘嗛亶鎵�鏈夌殑瀛愮粍浠惰妭鐐� + for (let i = 0; i < children.length; i++) { + const child = children[i] + // 鎷垮埌瀛愮粍浠剁殑瀛愮粍浠� + const grandChild = child.$children + // 鍒ゆ柇濡傛灉鍦ㄩ渶瑕侀噸鏂板垵濮嬪寲鐨勭粍浠舵暟缁勪腑鍚嶄腑锛屽苟涓斿瓨鍦╥nit鏂规硶鐨勮瘽锛屽垯鎵ц + if (names.includes(child.$options.name) && typeof child?.init === 'function') { + // 闇�瑕佽繘琛屼竴瀹氱殑寤舵椂锛屽洜涓哄垵濮嬪寲椤甸潰闇�瑕佹椂闂� + uni.$u.sleep(50).then(() => { + child.init() + }) + } + // 濡傛灉瀛愮粍浠惰繕鏈夊瓩缁勪欢锛岃繘琛岄�掑綊鍘嗛亶 + if (grandChild.length) { + this.retryComputedComponentRect(grandChild) + } + } + } + // #endif + } + } +</script> + +<style lang="scss" scoped> + @import "../../libs/css/components.scss"; + $u-popup-flex:1 !default; + $u-popup-content-background-color: #fff !default; + + .u-popup { + flex: $u-popup-flex; + + &__content { + background-color: $u-popup-content-background-color; + position: relative; + + &--round-top { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; + } + + &--round-left { + border-top-left-radius: 0; + border-top-right-radius: 10px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 10px; + } + + &--round-right { + border-top-left-radius: 10px; + border-top-right-radius: 0; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 0; + } + + &--round-bottom { + border-top-left-radius: 10px; + border-top-right-radius: 10px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + + &--round-center { + border-top-left-radius: 10px; + border-top-right-radius: 10px; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; + } + + &__close { + position: absolute; + + &--hover { + opacity: 0.4; + } + } + + &__close--top-left { + top: 15px; + left: 15px; + } + + &__close--top-right { + top: 15px; + right: 15px; + } + + &__close--bottom-left { + bottom: 15px; + left: 15px; + } + + &__close--bottom-right { + right: 15px; + bottom: 15px; + } + } + } +</style> -- Gitblit v1.9.3