<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>
							 |