You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
327 lines
7.1 KiB
327 lines
7.1 KiB
<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> |
|
|
|
|
|
<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 linkagePicker from "./linkage-picker.vue" |
|
export default { |
|
name:"w-picker", |
|
components:{ |
|
datePicker, |
|
rangePicker, |
|
halfPicker, |
|
timePicker, |
|
selectorPicker, |
|
shorttermPicker, |
|
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>
|
|
|