You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

286 lines
6.7 KiB
Vue

11 months ago
<template name="w-picker">
<view class="w-picker" :key="createKey" :data-key="createKey">
11 months ago
<view class="mask" :class="{ visible: visible }" @tap="onCancel" @touchmove.stop.prevent catchtouchmove="true"></view>
11 months ago
<view class="w-picker-cnt" :class="{ visible: visible }">
11 months ago
<view class="w-picker-header" @touchmove.stop.prevent catchtouchmove="true">
<text style="font-size: 18px">请选择时间</text>
11 months ago
<text @tap.stop.prevent="onCancel">
<u-icon name="close-circle" size="26"></u-icon>
</text>
<slot></slot>
<!-- <text :style="{ color: themeColor }" @tap.stop.prevent="pickerConfirm"
>确定</text
> -->
</view>
11 months ago
<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"
:disabledBefore="disabledBefore"
@change="handlerChange" @touchstart="touchStart" @touchend="touchEnd">
11 months ago
</date-picker>
11 months ago
<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">
11 months ago
</range-picker>
11 months ago
<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">
11 months ago
</half-picker>
<view style="margin-bottom: 10px">
11 months ago
<u-button width="" text="确定" shape="circle" :style="{
color: '#fff',
width: '500upx',
backgroundColor: '#1936C9',
}" @click="pickerConfirm"></u-button>
11 months ago
</view>
</view>
</view>
</template>
<script>
import datePicker from "./date-picker.vue";
import rangePicker from "./range-picker.vue";
import halfPicker from "./half-picker.vue";
export default {
name: "w-picker",
components: {
datePicker,
rangePicker,
halfPicker,
},
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,
},
//不是插件自带为了组件复用故意传参数
11 months ago
timeType: {
11 months ago
type: String,
11 months ago
default: "",
},
// disabledMonth: {
// type: Number,
// default: 0,
// },
// disabledRange: {
// type: Array,
// default: ''
// },
disabledBefore: {
type: Boolean,
default: false,
11 months ago
}
},
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;
11 months ago
this.result = { ...res };
11 months ago
},
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;
}
11 months ago
this.$emit("confirm", { timeType: this.timeType, ...this.result });
11 months ago
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;
}
11 months ago
11 months ago
.w-picker {
z-index: 888;
11 months ago
11 months ago
.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;
}
11 months ago
11 months ago
.mask.visible {
visibility: visible;
opacity: 1;
}
11 months ago
11 months ago
.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;
}
11 months ago
11 months ago
.w-picker-cnt.visible {
transform: translateY(0);
}
11 months ago
11 months ago
.w-picker-header {
display: flex;
align-items: center;
padding: 12upx 30upx;
height: 88upx;
background-color: #fff;
position: relative;
text-align: center;
font-size: 32upx;
justify-content: space-between;
border-bottom: solid 1px #eee;
border-radius: 10upx 0;
11 months ago
11 months ago
.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>