fonchat/components/w-picker/w-picker.vue
2023-10-25 10:02:04 +08:00

286 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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 style="font-size: 18px">请选择时间</text>
<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>
<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">
</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>
<view style="margin-bottom: 10px">
<u-button width="" text="确定" shape="circle" :style="{
color: '#fff',
width: '500upx',
backgroundColor: '#1936C9',
}" @click="pickerConfirm"></u-button>
</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,
},
//不是插件自带为了组件复用故意传参数
timeType: {
type: String,
default: "",
},
// disabledMonth: {
// type: Number,
// default: 0,
// },
// disabledRange: {
// type: Array,
// default: ''
// },
disabledBefore: {
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", { timeType: this.timeType, ...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: 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;
.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>