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