| 
						 | 
						- <template>
 - 	<view class="uv-drop-down-popup">
 - 		<uv-transition :show="show" mode="fade" :duration="300" :custom-style="overlayStyle" @click="clickOverlay">
 - 			<view class="uv-dp__container" ref="uvDPContainer" :style="{height: `${height}px`}" @click.stop="blockClick">
 - 				<view class="uv-dp__container__list" ref="uvDPList">
 - 					<slot>
 - 						<view class="uv-dp__container__list--item" v-for="(item,index) in list" :key="index" @click="clickHandler(item,index)" :style="[itemCustomStyle(index)]">
 - 							<uv-text :text="item[keyName]" :size="getTextSize(index)" :color="getTextColor(index)"></uv-text>
 - 						</view>
 - 					</slot>
 - 				</view>
 - 			</view>
 - 		</uv-transition>
 - 	</view>
 - </template>
 - <script>
 - 	import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js';
 - 	import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js';
 - 	// #ifdef APP-NVUE
 - 	const animation = uni.requireNativePlugin('animation');
 - 	const dom = uni.requireNativePlugin('dom');
 - 	// #endif
 - 	/**
 - 	 * DropDownPopup 下拉框
 - 	 * @description 下拉筛选框
 - 	 * @tutorial https://ext.dcloud.net.cn/plugin?name=uv-drop-down
 - 	 * @property {String | Number} name 字段标识
 - 	 * @property {String | Number} zIndex 弹出层的层级
 - 	 * @property {String | Number} opacity 遮罩层的透明度
 - 	 * @property {Boolean} clickOverlayOnClose 是否允许点击遮罩层关闭弹窗
 - 	 * @property {Object} currentDropItem 当前下拉筛选菜单对象
 - 	 * @property {String} keyName 指定从当前下拉筛选菜单对象元素中读取哪个属性作为文本展示
 - 	 */
 - 	export default {
 - 		name: 'uv-drop-down-popup',
 - 		mixins: [mpMixin, mixin],
 - 		props: {
 - 			sign: {
 - 				type: [String, Number],
 - 				default: 'UVDROPDOWN'
 - 			},
 - 			zIndex: {
 - 				type: [Number, String],
 - 				default: 999
 - 			},
 - 			opacity: {
 - 				type: [Number, String],
 - 				default: 0.5
 - 			},
 - 			clickOverlayOnClose: {
 - 				type: Boolean,
 - 				default: true
 - 			},
 - 			// 当前下拉选项对象
 - 			currentDropItem: {
 - 				type: Object,
 - 				default () {
 - 					return {
 - 						activeIndex: 0,
 - 						child: []
 - 					}
 - 				}
 - 			},
 - 			keyName: {
 - 				type: String,
 - 				default: 'label'
 - 			}
 - 		},
 - 		data() {
 - 			return {
 - 				show: false,
 - 				rect: {},
 - 				height: 0
 - 			}
 - 		},
 - 		computed: {
 - 			overlayStyle() {
 - 				let { height = 0, top = 0 } = this.rect;
 - 				// #ifdef H5
 - 				top += this.$uv.sys().windowTop;
 - 				// #endif
 - 				const style = {
 - 					position: 'fixed',
 - 					top: `${top+height}px`,
 - 					left: 0,
 - 					right: 0,
 - 					zIndex: this.zIndex,
 - 					bottom: 0,
 - 					'background-color': `rgba(0, 0, 0, ${this.opacity})`
 - 				}
 - 				return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle))
 - 			},
 - 			list() {
 - 				try {
 - 					return Array.isArray(this.currentDropItem.child) ? this.currentDropItem.child : [];
 - 				} catch (e) {
 - 					return [];
 - 				}
 - 			},
 - 			getTextColor(index) {
 - 				return index => {
 - 					const active = this.currentDropItem.activeIndex == index;
 - 					const color = this.currentDropItem.color;
 - 					const activeColor = this.currentDropItem.activeColor;
 - 					if (active) {
 - 						return activeColor ? activeColor : '#3c9cff';
 - 					}
 - 					return color ? color : '#333';
 - 				}
 - 			},
 - 			getTextSize(index) {
 - 				return index => {
 - 					const active = this.currentDropItem.activeIndex == index;
 - 					const size = this.currentDropItem.size;
 - 					const activeSize = this.currentDropItem.activeSize;
 - 					if (active) {
 - 						return activeSize ? activeSize : '30rpx';
 - 					}
 - 					return size ? size : '30rpx';
 - 				}
 - 			},
 - 			itemCustomStyle() {
 - 				return index => {
 - 					const active = this.currentDropItem.activeIndex == index;
 - 					const style = {};
 - 					if (active && this.currentDropItem.itemActiveCustomStyle) {
 - 						return this.$uv.deepMerge(style, this.$uv.addStyle(this.currentDropItem.itemActiveCustomStyle));
 - 					}
 - 					if (this.currentDropItem.itemCustomStyle) {
 - 						return this.$uv.deepMerge(style, this.$uv.addStyle(this.currentDropItem.itemCustomStyle))
 - 					}
 - 					return style;
 - 				}
 - 			}
 - 		},
 - 		created() {
 - 			this.init();
 - 		},
 - 		methods: {
 - 			blockClick() {},
 - 			clickHandler(item, index) {
 - 				this.currentDropItem.activeIndex = index;
 - 				this.$emit('clickItem', item);
 - 				this.close();
 - 			},
 - 			init() {
 - 				uni.$off(`${this.sign}_GETRECT`);
 - 				uni.$on(`${this.sign}_GETRECT`, rect => {
 - 					this.rect = rect;
 - 				})
 - 				uni.$off(`${this.sign}_CLICKMENU`);
 - 				uni.$on(`${this.sign}_CLICKMENU`, async res => {
 - 					if (res.show) {
 - 						this.open();
 - 					} else {
 - 						this.close();
 - 					}
 - 				})
 - 			},
 - 			open() {
 - 				this.show = true;
 - 				this.$nextTick(async () => {
 - 					// #ifndef H5 || MP-WEIXIN
 - 					await this.$uv.sleep(60);
 - 					// #endif
 - 					const res = await this.queryRect();
 - 					// #ifndef APP-NVUE
 - 					this.height = res.height;
 - 					// #endif
 - 					// #ifdef APP-NVUE
 - 					this.animation(res.height);
 - 					// #endif
 - 					this.$emit('popupChange', { show: true });
 - 				})
 - 			},
 - 			close() {
 - 				if(!this.show) return;
 - 				this.height = 0;
 - 				// #ifndef APP-NVUE
 - 				this.height = 0;
 - 				// #endif
 - 				// #ifdef APP-NVUE
 - 				this.animation(0);
 - 				// #endif
 - 				this.show = false;
 - 				uni.$emit(`${this.sign}_CLOSEPOPUP`);
 - 				this.$emit('popupChange', { show: false });
 - 			},
 - 			clickOverlay() {
 - 				if (this.clickOverlayOnClose) {
 - 					this.close();
 - 				}
 - 			},
 - 			// 查询内容高度
 - 			queryRect() {
 - 				// #ifndef APP-NVUE
 - 				// 组件内部一般用this.$uvGetRect,对外的为getRect,二者功能一致,名称不同
 - 				return new Promise(resolve => {
 - 					this.$uvGetRect(`.uv-dp__container__list`).then(size => {
 - 						resolve(size)
 - 					})
 - 				})
 - 				// #endif
 - 				// #ifdef APP-NVUE
 - 				// nvue下,使用dom模块查询元素高度
 - 				// 返回一个promise,让调用此方法的主体能使用then回调
 - 				return new Promise(resolve => {
 - 					dom.getComponentRect(this.$refs.uvDPList, res => {
 - 						resolve(res.size)
 - 					})
 - 				})
 - 				// #endif
 - 			},
 - 			// nvue下设置高度
 - 			animation(height, duration = 200) {
 - 				// #ifdef APP-NVUE
 - 				const ref = this.$refs['uvDPContainer'];
 - 				animation.transition(ref, {
 - 					styles: {
 - 						height: `${height}px`
 - 					},
 - 					duration
 - 				})
 - 				// #endif
 - 			}
 - 		}
 - 	}
 - </script>
 - <style scoped lang="scss">
 - 	.uv-dp__container {
 - 		/* #ifndef APP-NVUE */
 - 		overflow: hidden;
 - 		transition: all .15s;
 - 		/* #endif */
 - 		background-color: #fff;
 - 	}
 - 	.uv-dp__container__list {
 - 		&--item {
 - 			padding: 20rpx 60rpx;
 - 		}
 - 	}
 - </style>
 
 
  |