mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	
		
			
	
	
		
			341 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
		
		
			
		
	
	
			341 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
|   | <template name="w-picker"> | |||
|  | 	<view class="w-picker" :key="createKey" :data-key="createKey"> | |||
|  | 		<view class="mask" :class="{'visible':visible}" @tap="onCancel" @touchmove.stop.prevent catchtouchmove="true"></view> | |||
|  | 		<view class="w-picker-cnt" :class="{'visible':visible}"> | |||
|  | 			<view class="w-picker-header"  @touchmove.stop.prevent catchtouchmove="true"> | |||
|  | 				<text @tap.stop.prevent="onCancel">取消</text> | |||
|  | 				<slot></slot> | |||
|  | 				<text :style="{'color':themeColor}" @tap.stop.prevent="pickerConfirm">确定</text> | |||
|  | 			</view> | |||
|  | 			<date-picker  | |||
|  | 				v-if="mode=='date'"  | |||
|  | 				class="w-picker-wrapper" | |||
|  | 				:startYear="startYear" | |||
|  | 				:endYear="endYear" | |||
|  | 				:value="value" | |||
|  | 				:fields="fields" | |||
|  | 				:item-height="itemHeight" | |||
|  | 				:current="current" | |||
|  | 				:disabled-after="disabledAfter" | |||
|  | 				@change="handlerChange" | |||
|  | 				@touchstart="touchStart"  | |||
|  | 				@touchend="touchEnd"> | |||
|  | 			</date-picker> | |||
|  | 			 | |||
|  | 			<range-picker | |||
|  | 				v-if="mode=='range'"  | |||
|  | 				class="w-picker-wrapper" | |||
|  | 				:startYear="startYear" | |||
|  | 				:endYear="endYear" | |||
|  | 				:value="value" | |||
|  | 				:item-height="itemHeight" | |||
|  | 				:current="current" | |||
|  | 				@change="handlerChange" | |||
|  | 				@touchstart="touchStart"  | |||
|  | 				@touchend="touchEnd"> | |||
|  | 			</range-picker> | |||
|  | 			 | |||
|  | 			<half-picker | |||
|  | 				v-if="mode=='half'"  | |||
|  | 				class="w-picker-wrapper" | |||
|  | 				:startYear="startYear" | |||
|  | 				:endYear="endYear" | |||
|  | 				:value="value" | |||
|  | 				:item-height="itemHeight" | |||
|  | 				:current="current" | |||
|  | 				:disabled-after="disabledAfter" | |||
|  | 				@change="handlerChange" | |||
|  | 				@touchstart="touchStart"  | |||
|  | 				@touchend="touchEnd"> | |||
|  | 			</half-picker> | |||
|  | 			 | |||
|  | 			<shortterm-picker | |||
|  | 				v-if="mode=='shortTerm'"  | |||
|  | 				class="w-picker-wrapper" | |||
|  | 				:startYear="startYear" | |||
|  | 				:endYear="endYear" | |||
|  | 				:value="value" | |||
|  | 				:item-height="itemHeight" | |||
|  | 				:current="current" | |||
|  | 				expand="60" | |||
|  | 				:disabled-after="disabledAfter" | |||
|  | 				@change="handlerChange" | |||
|  | 				@touchstart="touchStart"  | |||
|  | 				@touchend="touchEnd"> | |||
|  | 			</shortterm-picker> | |||
|  | 			 | |||
|  | 			<time-picker | |||
|  | 				v-if="mode=='time'" | |||
|  | 				class="w-picker-wrapper" | |||
|  | 				:value="value" | |||
|  | 				:item-height="itemHeight" | |||
|  | 				:current="current" | |||
|  | 				:disabled-after="disabledAfter" | |||
|  | 				:second="second" | |||
|  | 				@change="handlerChange" | |||
|  | 				@touchstart="touchStart"  | |||
|  | 				@touchend="touchEnd"> | |||
|  | 			</time-picker> | |||
|  | 			 | |||
|  | 			<selector-picker | |||
|  | 				v-if="mode=='selector'" | |||
|  | 				class="w-picker-wrapper" | |||
|  | 				:value="value" | |||
|  | 				:item-height="itemHeight" | |||
|  | 				:options="options" | |||
|  | 				:default-type="defaultType" | |||
|  | 				:default-props="defaultProps" | |||
|  | 				@change="handlerChange" | |||
|  | 				@touchstart="touchStart"  | |||
|  | 				@touchend="touchEnd"> | |||
|  | 			</selector-picker> | |||
|  | 			 | |||
|  | 			<region-picker | |||
|  | 				v-if="mode=='region'" | |||
|  | 				class="w-picker-wrapper" | |||
|  | 				:value="value" | |||
|  | 				:hide-area="hideArea" | |||
|  | 				:default-type="defaultType" | |||
|  | 				:item-height="itemHeight" | |||
|  | 				@change="handlerChange" | |||
|  | 				@touchstart="touchStart"  | |||
|  | 				@touchend="touchEnd"> | |||
|  | 			</region-picker> | |||
|  | 			 | |||
|  | 			<linkage-picker | |||
|  | 				v-if="mode=='linkage'" | |||
|  | 				class="w-picker-wrapper" | |||
|  | 				:value="value" | |||
|  | 				:options="options" | |||
|  | 				:level="level" | |||
|  | 				:default-type="defaultType" | |||
|  | 				:default-props="defaultProps" | |||
|  | 				:item-height="itemHeight" | |||
|  | 				@change="handlerChange" | |||
|  | 				@touchstart="touchStart"  | |||
|  | 				@touchend="touchEnd"> | |||
|  | 			</linkage-picker> | |||
|  | 		</view> | |||
|  | 	</view> | |||
|  | </template> | |||
|  | 
 | |||
|  | <script> | |||
|  | 	import datePicker from "./date-picker.vue" | |||
|  | 	import rangePicker from "./range-picker.vue" | |||
|  | 	import halfPicker from "./half-picker.vue" | |||
|  | 	import shorttermPicker from "./shortterm-picker.vue" | |||
|  | 	import timePicker from "./time-picker.vue" | |||
|  | 	import selectorPicker from "./selector-picker.vue" | |||
|  | 	import regionPicker from "./region-picker.vue" | |||
|  | 	import linkagePicker from "./linkage-picker.vue" | |||
|  | 	export default { | |||
|  | 		name:"w-picker", | |||
|  | 		components:{ | |||
|  | 			datePicker, | |||
|  | 			rangePicker, | |||
|  | 			halfPicker, | |||
|  | 			timePicker, | |||
|  | 			selectorPicker, | |||
|  | 			shorttermPicker, | |||
|  | 			regionPicker, | |||
|  | 			linkagePicker | |||
|  | 		}, | |||
|  | 		props:{ | |||
|  | 			mode:{ | |||
|  | 				type:String, | |||
|  | 				default:"date" | |||
|  | 			}, | |||
|  | 			value:{//默认值
 | |||
|  | 				type:[String,Array,Number], | |||
|  | 				default:"" | |||
|  | 			}, | |||
|  | 			current:{//是否默认显示当前时间,如果是,传的默认值将失效
 | |||
|  | 				type:Boolean, | |||
|  | 				default:false | |||
|  | 			}, | |||
|  | 			themeColor:{//确认按钮主题颜色
 | |||
|  | 				type:String, | |||
|  | 				default:"#f5a200" | |||
|  | 			}, | |||
|  | 			fields:{//日期颗粒度:year、month、day、hour、minute、second
 | |||
|  | 				type:String, | |||
|  | 				default:"date" | |||
|  | 			}, | |||
|  | 			disabledAfter:{//是否禁用当前之后的日期
 | |||
|  | 				type:Boolean, | |||
|  | 				default:false | |||
|  | 			}, | |||
|  | 			second:{//time-picker是否显示秒
 | |||
|  | 				type:Boolean, | |||
|  | 				default:true | |||
|  | 			}, | |||
|  | 			options:{//selector,region数据源
 | |||
|  | 				type:[Array,Object], | |||
|  | 				default(){ | |||
|  | 					return [] | |||
|  | 				} | |||
|  | 			}, | |||
|  | 			defaultProps:{//selector,linkagle字段转换配置
 | |||
|  | 				type:Object, | |||
|  | 				default(){ | |||
|  | 					return{ | |||
|  | 						label:"label", | |||
|  | 						value:"value", | |||
|  | 						children:"children" | |||
|  | 					} | |||
|  | 				} | |||
|  | 			}, | |||
|  | 			defaultType:{ | |||
|  | 				type:String, | |||
|  | 				default:"label" | |||
|  | 			}, | |||
|  | 			hideArea:{//mode=region时,是否隐藏区县列
 | |||
|  | 				type:Boolean, | |||
|  | 				default:false | |||
|  | 			}, | |||
|  | 			level:{ | |||
|  | 				//多级联动层级,表示几级联动,区间2-4;
 | |||
|  | 				type:[Number,String], | |||
|  | 				default:2 | |||
|  | 			}, | |||
|  | 			timeout:{//是否开启点击延迟,当快速滚动 还没有滚动完毕点击关闭时得到的值是不准确的
 | |||
|  | 				type:Boolean, | |||
|  | 				default:false | |||
|  | 			}, | |||
|  | 			expand:{//mode=shortterm 默认往后拓展天数
 | |||
|  | 				type:[Number,String], | |||
|  | 				default:30 | |||
|  | 			}, | |||
|  | 			startYear:{ | |||
|  | 				type:[String,Number], | |||
|  | 				default:1970 | |||
|  | 			}, | |||
|  | 			endYear:{ | |||
|  | 				type:[String,Number], | |||
|  | 				default:new Date().getFullYear() | |||
|  | 			}, | |||
|  | 			visible:{ | |||
|  | 				type:Boolean, | |||
|  | 				default:false | |||
|  | 			} | |||
|  | 		}, | |||
|  | 		created() { | |||
|  | 			this.createKey=Math.random()*1000; | |||
|  | 		}, | |||
|  | 		data() { | |||
|  | 			return { | |||
|  | 				itemHeight:`height: ${uni.upx2px(88)}px;`, | |||
|  | 				result:{}, | |||
|  | 				confirmFlag:true | |||
|  | 			}; | |||
|  | 		}, | |||
|  | 		methods:{ | |||
|  | 			touchStart(){ | |||
|  | 				if(this.timeout){ | |||
|  | 					this.confirmFlag=false; | |||
|  | 				} | |||
|  | 			}, | |||
|  | 			touchEnd(){ | |||
|  | 				if(this.timeout){ | |||
|  | 					setTimeout(()=>{ | |||
|  | 						this.confirmFlag=true; | |||
|  | 					},500) | |||
|  | 				} | |||
|  | 			}, | |||
|  | 			handlerChange(res){ | |||
|  | 				let _this=this; | |||
|  | 				this.result={...res}; | |||
|  | 			}, | |||
|  | 			show(){ | |||
|  | 				this.$emit("update:visible",true); | |||
|  | 			}, | |||
|  | 			hide(){ | |||
|  | 				this.$emit("update:visible",false); | |||
|  | 			}, | |||
|  | 			onCancel(res){ | |||
|  | 				this.$emit("update:visible",false); | |||
|  | 				this.$emit("cancel"); | |||
|  | 			}, | |||
|  | 			pickerConfirm(){ | |||
|  | 				if(!this.confirmFlag){ | |||
|  | 					return; | |||
|  | 				}; | |||
|  | 				this.$emit("confirm",this.result); | |||
|  | 				this.$emit("update:visible",false); | |||
|  | 			} | |||
|  | 		} | |||
|  | 	} | |||
|  | </script> | |||
|  | 
 | |||
|  | <style lang="scss"> | |||
|  | 	.w-picker-item { | |||
|  | 	  text-align: center; | |||
|  | 	  width: 100%; | |||
|  | 	  height: 88upx; | |||
|  | 	  line-height: 88upx; | |||
|  | 	  text-overflow: ellipsis; | |||
|  | 	  white-space: nowrap; | |||
|  | 	  font-size: 30upx; | |||
|  | 	} | |||
|  | 	.w-picker{ | |||
|  | 		z-index: 888; | |||
|  | 		.mask { | |||
|  | 		  position: fixed; | |||
|  | 		  z-index: 1000; | |||
|  | 		  top: 0; | |||
|  | 		  right: 0; | |||
|  | 		  left: 0; | |||
|  | 		  bottom: 0; | |||
|  | 		  background: rgba(0, 0, 0, 0.6); | |||
|  | 		  visibility: hidden; | |||
|  | 		  opacity: 0; | |||
|  | 		  transition: all 0.3s ease; | |||
|  | 		} | |||
|  | 		.mask.visible{ | |||
|  | 			visibility: visible; | |||
|  | 			opacity: 1; | |||
|  | 		} | |||
|  | 		.w-picker-cnt { | |||
|  | 		  position: fixed; | |||
|  | 		  bottom: 0; | |||
|  | 		  left: 0; | |||
|  | 		  width: 100%; | |||
|  | 		  transition: all 0.3s ease; | |||
|  | 		  transform: translateY(100%); | |||
|  | 		  z-index: 3000; | |||
|  | 		  background-color: #fff; | |||
|  | 		} | |||
|  | 		.w-picker-cnt.visible { | |||
|  | 		  transform: translateY(0); | |||
|  | 		} | |||
|  | 		.w-picker-header{ | |||
|  | 		  display: flex; | |||
|  | 		  align-items: center; | |||
|  | 		  padding: 0 30upx; | |||
|  | 		  height: 88upx; | |||
|  | 		  background-color: #fff; | |||
|  | 		  position: relative; | |||
|  | 		  text-align: center; | |||
|  | 		  font-size: 32upx; | |||
|  | 		  justify-content: space-between; | |||
|  | 		  border-bottom: solid 1px #eee; | |||
|  | 		  .w-picker-btn{ | |||
|  | 		  	font-size: 30upx; | |||
|  | 		  } | |||
|  | 		} | |||
|  | 		 | |||
|  | 		.w-picker-hd:after { | |||
|  | 		  content: ' '; | |||
|  | 		  position: absolute; | |||
|  | 		  left: 0; | |||
|  | 		  bottom: 0; | |||
|  | 		  right: 0; | |||
|  | 		  height: 1px; | |||
|  | 		  border-bottom: 1px solid #e5e5e5; | |||
|  | 		  color: #e5e5e5; | |||
|  | 		  transform-origin: 0 100%; | |||
|  | 		  transform: scaleY(0.5); | |||
|  | 		} | |||
|  | 	} | |||
|  | </style> |