♻️(component): datePicker 重构
This commit is contained in:
parent
3fc0c38362
commit
188f16a34a
@ -0,0 +1,160 @@
|
|||||||
|
<template>
|
||||||
|
<div class="layui-laydate">
|
||||||
|
<div class="layui-laydate-main laydate-main-list-0">
|
||||||
|
<div class="layui-laydate-header">
|
||||||
|
<i class="layui-icon laydate-icon laydate-prev-y" @click="changeYearOrMonth('year', -1)"></i>
|
||||||
|
<i class="layui-icon laydate-icon laydate-prev-m" @click="changeYearOrMonth('month', -1)"></i>
|
||||||
|
<div class="laydate-set-ym">
|
||||||
|
<span @click="datePicker.showPanel.value = 'year'">{{ datePicker.currentYear.value }} 年</span>
|
||||||
|
<span @click="datePicker.showPanel.value = 'month'">{{ datePicker.currentMonth.value + 1 }} 月</span>
|
||||||
|
</div>
|
||||||
|
<i class="layui-icon laydate-icon laydate-next-m" @click="changeYearOrMonth('month', 1)"></i>
|
||||||
|
<i class="layui-icon laydate-icon laydate-next-y" @click="changeYearOrMonth('year', 1)"></i>
|
||||||
|
</div>
|
||||||
|
<div class="layui-laydate-content">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th v-for="item of WEEK_NAME" :key="item">{{ item }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<template v-for="(o, i) of datePicker.dateList.value.length % 7 == 0
|
||||||
|
? datePicker.dateList.value.length / 7
|
||||||
|
: Math.floor(datePicker.dateList.value.length / 7) + 1" :key="i">
|
||||||
|
<tr>
|
||||||
|
<td v-for="(item, index) of datePicker.dateList.value.slice(
|
||||||
|
i * 7,
|
||||||
|
i * 7 + 7
|
||||||
|
)" :key="index" :data-unix="item.value" :class="{
|
||||||
|
'laydate-day-prev': item.type !== 'current',
|
||||||
|
'layui-this': item.value === datePicker.currentDay.value || (range && (item.value == parseInt(rangeValue.first) || item.value == parseInt(rangeValue.last))),
|
||||||
|
'laydate-range-hover': ifHasRangeHoverClass(item),
|
||||||
|
}" @click="handleDayClick(item)" @mouseenter="dayItemMouseEnter($event, item)">
|
||||||
|
{{ item.day }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<PanelFoot></PanelFoot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: "DatePanel",
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, inject, ref, watch } from 'vue';
|
||||||
|
import { provideType } from '../interface';
|
||||||
|
import { setDateList } from '../day';
|
||||||
|
import PanelFoot from './PanelFoot.vue'
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
range?: boolean,
|
||||||
|
rangeValue?: { first: string, last: string, hover: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
range: false,
|
||||||
|
rangeValue: () => { return { first: '', last: '', hover: '' } }
|
||||||
|
});
|
||||||
|
|
||||||
|
const datePicker: provideType = inject('datePicker') as provideType;
|
||||||
|
const WEEK_NAME = ["日", "一", "二", "三", "四", "五", "六"];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 监听年月, 刷新日期
|
||||||
|
watch(
|
||||||
|
[datePicker.currentYear, datePicker.currentMonth],
|
||||||
|
() => {
|
||||||
|
datePicker.dateList.value = setDateList(datePicker.currentYear.value, datePicker.currentMonth.value);
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 切换年月
|
||||||
|
const changeYearOrMonth = (type: "year" | "month", num: number) => {
|
||||||
|
if (type === "year") {
|
||||||
|
datePicker.currentYear.value += num;
|
||||||
|
} else {
|
||||||
|
let month = datePicker.currentMonth.value + num;
|
||||||
|
if (month > 11) {
|
||||||
|
month = 0;
|
||||||
|
datePicker.currentYear.value++;
|
||||||
|
} else if (month < 0) {
|
||||||
|
month = 11;
|
||||||
|
datePicker.currentYear.value--;
|
||||||
|
}
|
||||||
|
datePicker.currentMonth.value = month;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 点击日期
|
||||||
|
const handleDayClick = (item: any) => {
|
||||||
|
if (props.range) {
|
||||||
|
if (item.type !== "current") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
datePicker.currentDay.value = item.value;
|
||||||
|
|
||||||
|
if (item.type !== "current") {
|
||||||
|
datePicker.currentMonth.value = item.type === "prev" ? datePicker.currentMonth.value - 1 : datePicker.currentMonth.value + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.range) {
|
||||||
|
if (props.rangeValue.first === '' && props.rangeValue.last === '') {
|
||||||
|
//props.rangeValue.first = item.value
|
||||||
|
} else if (props.rangeValue.first !== '' && props.rangeValue.last !== '') {
|
||||||
|
// rangeValue.first = item.value
|
||||||
|
// rangeValue.last = ''
|
||||||
|
} else if (props.rangeValue.first !== '' && props.rangeValue.last === '') {
|
||||||
|
//rangeValue.last = item.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const dayItemMouseEnter = (event: MouseEvent, item: any) => {
|
||||||
|
if (!props.range) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!props.rangeValue.first) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (item.type !== 'current') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//rpropsangeValue.hover = (event.target as HTMLElement).dataset.unix as string
|
||||||
|
}
|
||||||
|
const ifHasRangeHoverClass = computed(() => {
|
||||||
|
return function (item: any) {
|
||||||
|
if (!props.range) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!props.rangeValue.first) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (item.type !== 'current') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (item.value == parseInt(props.rangeValue.first) || item.value == parseInt(props.rangeValue.last)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let hover = props.rangeValue.last ? props.rangeValue.last : props.rangeValue.hover;
|
||||||
|
let max = props.rangeValue.first > hover ? props.rangeValue.first : hover;
|
||||||
|
let min = props.rangeValue.first < hover ? props.rangeValue.first : hover
|
||||||
|
if (item.value >= parseInt(min) && item.value <= parseInt(max)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<div class="layui-laydate">
|
||||||
|
<div class="layui-laydate-main laydate-main-list-0 laydate-ym-show">
|
||||||
|
<div class="layui-laydate-header">
|
||||||
|
<i class="layui-icon laydate-icon laydate-prev-y" @click="changeYearOrMonth('year', -1)"></i>
|
||||||
|
<div class="laydate-set-ym">
|
||||||
|
<span @click="datePicker.showPanel.value = 'month'">{{ datePicker.currentMonth.value + 1 }} 月</span>
|
||||||
|
</div>
|
||||||
|
<i class="layui-icon laydate-icon laydate-next-y" @click="changeYearOrMonth('year', 1)"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="layui-laydate-content" style="height: 220px">
|
||||||
|
<ul class="layui-laydate-list laydate-month-list">
|
||||||
|
<li v-for="item of MONTH_NAME" :key="item"
|
||||||
|
:class="{ 'layui-this': MONTH_NAME.indexOf(item) === datePicker.currentMonth.value }"
|
||||||
|
@click="handleMonthClick(item)">
|
||||||
|
{{ item.slice(0, 3) }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<PanelFoot></PanelFoot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: "TimePanel",
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { inject } from 'vue';
|
||||||
|
import { provideType } from '../interface';
|
||||||
|
import PanelFoot from './PanelFoot.vue'
|
||||||
|
const datePicker: provideType = inject('datePicker') as provideType;
|
||||||
|
|
||||||
|
|
||||||
|
const MONTH_NAME = [
|
||||||
|
"1月",
|
||||||
|
"2月",
|
||||||
|
"3月",
|
||||||
|
"4月",
|
||||||
|
"5月",
|
||||||
|
"6月",
|
||||||
|
"7月",
|
||||||
|
"8月",
|
||||||
|
"9月",
|
||||||
|
"10月",
|
||||||
|
"11月",
|
||||||
|
"12月",
|
||||||
|
];
|
||||||
|
|
||||||
|
// 切换年月
|
||||||
|
const changeYearOrMonth = (type: "year" | "month", num: number) => {
|
||||||
|
if (type === "year") {
|
||||||
|
datePicker.currentYear.value += num;
|
||||||
|
} else {
|
||||||
|
let month = datePicker.currentMonth.value + num;
|
||||||
|
if (month > 11) {
|
||||||
|
month = 0;
|
||||||
|
datePicker.currentYear.value++;
|
||||||
|
} else if (month < 0) {
|
||||||
|
month = 11;
|
||||||
|
datePicker.currentYear.value--;
|
||||||
|
}
|
||||||
|
datePicker.currentMonth.value = month;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 点击月份
|
||||||
|
const handleMonthClick = (item: any) => {
|
||||||
|
datePicker.currentMonth.value = MONTH_NAME.indexOf(item);
|
||||||
|
if (datePicker.type === "month") {
|
||||||
|
datePicker.currentDay.value = dayjs(datePicker.currentDay.value)
|
||||||
|
.month(MONTH_NAME.indexOf(item))
|
||||||
|
.valueOf();
|
||||||
|
} else if (datePicker.type === "yearmonth") {
|
||||||
|
datePicker.currentDay.value = dayjs(datePicker.currentDay.value)
|
||||||
|
.month(MONTH_NAME.indexOf(item))
|
||||||
|
.valueOf();
|
||||||
|
} else {
|
||||||
|
datePicker.showPanel.value = "date";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<div class="layui-laydate-footer">
|
||||||
|
<span v-if="datePicker.type === 'datetime' && datePicker.showPanel.value === 'datetime'" @click="chooseTime"
|
||||||
|
class="laydate-btns-time">选择时间</span>
|
||||||
|
|
||||||
|
<span v-else-if="datePicker.type === 'datetime' && datePicker.showPanel.value === 'time'"
|
||||||
|
@click="datePicker.showPanel.value = 'datetime'" class="laydate-btns-time">选择日期</span>
|
||||||
|
|
||||||
|
<span v-else-if="datePicker.type === 'yearmonth' && datePicker.showPanel.value === 'year'"
|
||||||
|
@click="datePicker.showPanel.value = 'month'" class="laydate-btns-time">选择月份</span>
|
||||||
|
<span v-else-if="datePicker.type === 'yearmonth' && datePicker.showPanel.value === 'month'"
|
||||||
|
@click="datePicker.showPanel.value = 'year'" class="laydate-btns-time">选择年份</span>
|
||||||
|
|
||||||
|
<span v-else-if="!datePicker.range" class="layui-laydate-preview" title="当前选中的结果">
|
||||||
|
<template v-if="datePicker.type === 'month'">{{ datePicker.currentMonth.value + 1 }}</template>
|
||||||
|
<template v-else-if="datePicker.type === 'year'">{{ datePicker.currentYear.value }}</template>
|
||||||
|
<template v-else-if="datePicker.type === 'time'">{{
|
||||||
|
datePicker.hms.value.hh + ':' + datePicker.hms.value.mm + ':' + (datePicker.hms.value.ss === 0 ? '0' : '') + datePicker.hms.value.ss
|
||||||
|
}}</template>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="laydate-footer-btns">
|
||||||
|
<span lay-type="clear" class="laydate-btns-clear" @click="datePicker.clear()">清空</span>
|
||||||
|
<span lay-type="now" class="laydate-btns-now" @click="datePicker.now()">现在</span>
|
||||||
|
<span lay-type="confirm" class="laydate-btns-confirm" @click="datePicker.ok()">确定</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: "PanelFoot",
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { inject } from 'vue';
|
||||||
|
import { provideType } from '../interface';
|
||||||
|
|
||||||
|
|
||||||
|
const datePicker: provideType = inject('datePicker') as provideType;
|
||||||
|
const emits = defineEmits(['showYearPanel', 'update:showPanel', 'scrollToCurrentTime', 'ok']);
|
||||||
|
|
||||||
|
//选择时间
|
||||||
|
const chooseTime = () => {
|
||||||
|
datePicker.showPanel.value = 'time'
|
||||||
|
//scrollToCurrentTime()
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div class="layui-laydate">
|
||||||
|
<div class="layui-laydate-main laydate-main-list-0 laydate-time-show">
|
||||||
|
<div class="layui-laydate-header">
|
||||||
|
<div class="laydate-set-ym">
|
||||||
|
<span class="laydate-time-text">选择时间</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-laydate-content" style="height: 210px">
|
||||||
|
<ul class="layui-laydate-list laydate-time-list" ref="timePanelRef">
|
||||||
|
<li class="num-list" v-for="item in els" :key="item.type" :data-type="item.type">
|
||||||
|
<ol class="scroll" @click="choseTime">
|
||||||
|
<li v-for="(it, index) in item.count" :id="item.type + index.toString()"
|
||||||
|
:data-value="index.toString().padStart(2, '0')" :data-type="item.type" :key="it" :class="[
|
||||||
|
'num',
|
||||||
|
index.toString().padStart(2, '0') == datePicker.hms.value[item.type]
|
||||||
|
? 'layui-this'
|
||||||
|
: '',
|
||||||
|
]">
|
||||||
|
{{ index.toString().padStart(2, "0") }}
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<PanelFoot></PanelFoot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: "TimePanel",
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { inject } from 'vue';
|
||||||
|
import { provideType } from '../interface';
|
||||||
|
import PanelFoot from './PanelFoot.vue'
|
||||||
|
const datePicker: provideType = inject('datePicker') as provideType;
|
||||||
|
const els = [
|
||||||
|
{ count: 24, type: "hh" },
|
||||||
|
{ count: 60, type: "mm" },
|
||||||
|
{ count: 60, type: "ss" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 点击时间 - hms
|
||||||
|
const choseTime = (e: any) => {
|
||||||
|
if (e.target.nodeName == "LI") {
|
||||||
|
let { value, type } = e.target.dataset;
|
||||||
|
datePicker.hms.value[type as keyof typeof datePicker.hms.value] = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div class="layui-laydate">
|
||||||
|
<div class="layui-laydate-main laydate-main-list-0 laydate-ym-show">
|
||||||
|
<div class="layui-laydate-header">
|
||||||
|
<div class="laydate-set-ym">
|
||||||
|
<span class="laydate-time-text">选择年份</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-laydate-content" style="height: 220px; overflow-y: auto" ref="yearmonthScrollRef">
|
||||||
|
<ul class="layui-laydate-list laydate-year-list">
|
||||||
|
<li v-for="item of datePicker.yearList.value" :key="item"
|
||||||
|
:class="{ 'layui-this': datePicker.currentYear.value === item }" @click="handleYearClick(item)">{{ item }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<PanelFoot></PanelFoot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: "YearPanel",
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { inject } from 'vue';
|
||||||
|
import { provideType } from '../interface';
|
||||||
|
import PanelFoot from './PanelFoot.vue'
|
||||||
|
const datePicker: provideType = inject('datePicker') as provideType;
|
||||||
|
|
||||||
|
// 点击年份
|
||||||
|
const handleYearClick = (item: any) => {
|
||||||
|
datePicker.currentYear.value = item;
|
||||||
|
if (datePicker.type === "year") {
|
||||||
|
datePicker.currentDay.value = dayjs().year(item).valueOf();
|
||||||
|
} else if (datePicker.type === "yearmonth") {
|
||||||
|
datePicker.currentDay.value = dayjs().year(item).valueOf();
|
||||||
|
datePicker.showPanel.value = "month";
|
||||||
|
} else {
|
||||||
|
datePicker.showPanel.value = "date";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -52,4 +52,47 @@ const getDayLength = (year: number, month: number): number => {
|
|||||||
return new Date(year, month + 1, 0).getDate();
|
return new Date(year, month + 1, 0).getDate();
|
||||||
};
|
};
|
||||||
|
|
||||||
export { getDayLength, getYears, getDate, getMonth, getYear, getDay };
|
|
||||||
|
// 设置日期列表
|
||||||
|
const setDateList = (year: number, month: number) => {
|
||||||
|
const curDays = getDayLength(year, month); // 当月天数
|
||||||
|
const prevDays = getDayLength(year, month - 1); // 上月天数
|
||||||
|
const curFirstDayWeek = new Date(year, month, 1).getDay(); // 当月第一天星期几
|
||||||
|
const list: any[] = [];
|
||||||
|
// 填充上月天数
|
||||||
|
for (let i = prevDays - curFirstDayWeek + 1; i <= prevDays; i++) {
|
||||||
|
list.push({
|
||||||
|
day: i,
|
||||||
|
value: +new Date(year, month - 1, i),
|
||||||
|
isRange: false,
|
||||||
|
isSelected: false,
|
||||||
|
type: "prev",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 填充当月天数
|
||||||
|
for (let i = 1; i <= curDays; i++) {
|
||||||
|
list.push({
|
||||||
|
day: i,
|
||||||
|
value: +new Date(year, month, i),
|
||||||
|
isRange: false,
|
||||||
|
isSelected: false,
|
||||||
|
type: "current",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 填充下月天数
|
||||||
|
const nextDays = 7 - (list.length % 7);
|
||||||
|
if (nextDays !== 7) {
|
||||||
|
for (let i = 1; i <= nextDays; i++) {
|
||||||
|
list.push({
|
||||||
|
day: i,
|
||||||
|
value: +new Date(year, month + 1, i),
|
||||||
|
isRange: false,
|
||||||
|
isSelected: false,
|
||||||
|
type: "next",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { getDayLength, getYears, getDate, getMonth, getYear,getDay,setDateList };
|
||||||
|
@ -459,3 +459,10 @@ html #layuicss-laydate {
|
|||||||
height: 71px;
|
height: 71px;
|
||||||
line-height: 71px;
|
line-height: 71px;
|
||||||
}
|
}
|
||||||
|
.laydate-range-hover{
|
||||||
|
background-color: var(--global-checked-color) !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
.layui-laydate-content .layui-disabled:hover{
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
@ -1,277 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<lay-dropdown ref="dropdownRef" :disabled="disabled" @open="openDropDown">
|
<lay-dropdown ref="dropdownRef" :disabled="disabled" @open="openDropDown">
|
||||||
<lay-input
|
<lay-input readonly :name="name" :model-value="dateValue" :placeholder="placeholder" prefix-icon="layui-icon-date"
|
||||||
readonly
|
:disabled="disabled">
|
||||||
:name="name"
|
|
||||||
:model-value="dateValue || modelValue"
|
|
||||||
:placeholder="placeholder"
|
|
||||||
prefix-icon="layui-icon-date"
|
|
||||||
:disabled="disabled"
|
|
||||||
>
|
|
||||||
</lay-input>
|
</lay-input>
|
||||||
<template #content>
|
<template #content>
|
||||||
<!-- 日期选择 -->
|
<!-- 日期选择 -->
|
||||||
<div
|
<DatePanel v-if="!range && (showPanel === 'date' || showPanel === 'datetime')">
|
||||||
class="layui-laydate"
|
</DatePanel>
|
||||||
v-show="showPane === 'date' || showPane === 'datetime'"
|
<!-- 时间选择 -->
|
||||||
>
|
<TimePanel v-if="!range && showPanel === 'time'"></TimePanel>
|
||||||
<div class="layui-laydate-main laydate-main-list-0">
|
|
||||||
<div class="layui-laydate-header">
|
|
||||||
<i
|
|
||||||
class="layui-icon laydate-icon laydate-prev-y"
|
|
||||||
@click="changeYearOrMonth('year', -1)"
|
|
||||||
></i
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="layui-icon laydate-icon laydate-prev-m"
|
|
||||||
@click="changeYearOrMonth('month', -1)"
|
|
||||||
></i
|
|
||||||
>
|
|
||||||
<div class="laydate-set-ym">
|
|
||||||
<span @click="showYearPanel">{{ currentYear }} 年</span>
|
|
||||||
<span @click="showPane = 'month'"
|
|
||||||
>{{ currentMonth + 1 }} 月</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<i
|
|
||||||
class="layui-icon laydate-icon laydate-next-m"
|
|
||||||
@click="changeYearOrMonth('month', 1)"
|
|
||||||
></i
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="layui-icon laydate-icon laydate-next-y"
|
|
||||||
@click="changeYearOrMonth('year', 1)"
|
|
||||||
></i
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="layui-laydate-content">
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th v-for="item of WEEK_NAME" :key="item">{{ item }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<template
|
|
||||||
v-for="(o, i) of dateList.length % 7 == 0
|
|
||||||
? dateList.length / 7
|
|
||||||
: Math.floor(dateList.length / 7) + 1"
|
|
||||||
:key="i"
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
v-for="(item, index) of dateList.slice(
|
|
||||||
i * 7,
|
|
||||||
i * 7 + 7
|
|
||||||
)"
|
|
||||||
:key="index"
|
|
||||||
:data-unix="item.value"
|
|
||||||
:class="{
|
|
||||||
'laydate-day-prev': item.type !== 'current',
|
|
||||||
'layui-this': item.value === currentDay,
|
|
||||||
}"
|
|
||||||
@click="handleDayClick(item)"
|
|
||||||
>
|
|
||||||
{{ item.day }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-laydate-footer">
|
|
||||||
<span
|
|
||||||
v-if="type === 'datetime'"
|
|
||||||
@click="
|
|
||||||
showPane = 'time';
|
|
||||||
scrollToCurrentTime();
|
|
||||||
"
|
|
||||||
class="laydate-btns-time"
|
|
||||||
>选择时间</span
|
|
||||||
>
|
|
||||||
<div class="laydate-footer-btns">
|
|
||||||
<span lay-type="clear" class="laydate-btns-clear" @click="clear"
|
|
||||||
>清空</span
|
|
||||||
>
|
|
||||||
<span lay-type="now" class="laydate-btns-now" @click="now"
|
|
||||||
>现在</span
|
|
||||||
>
|
|
||||||
<span lay-type="confirm" class="laydate-btns-confirm" @click="ok"
|
|
||||||
>确定</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 年份选择器 -->
|
<!-- 年份选择器 -->
|
||||||
<div
|
<YearPanel v-if="!range && (showPanel === 'year' || showPanel === 'yearmonth')"></YearPanel>
|
||||||
class="layui-laydate"
|
|
||||||
v-show="showPane === 'year' || showPane === 'yearmonth'"
|
|
||||||
>
|
|
||||||
<div class="layui-laydate-main laydate-main-list-0 laydate-ym-show">
|
|
||||||
<div class="layui-laydate-header">
|
|
||||||
<div class="laydate-set-ym">
|
|
||||||
<span class="laydate-time-text">选择年份</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="layui-laydate-content"
|
|
||||||
style="height: 220px; overflow-y: auto"
|
|
||||||
ref="yearmonthScrollRef"
|
|
||||||
>
|
|
||||||
<ul class="layui-laydate-list laydate-year-list">
|
|
||||||
<li
|
|
||||||
v-for="item of yearList"
|
|
||||||
:key="item"
|
|
||||||
:class="[{ 'layui-this': currentYear === item }]"
|
|
||||||
@click="handleYearClick(item)"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-laydate-footer">
|
|
||||||
<span
|
|
||||||
class="layui-laydate-preview"
|
|
||||||
title="当前选中的结果"
|
|
||||||
style="color: rgb(102, 102, 102)"
|
|
||||||
>{{ dateValue }}</span
|
|
||||||
>
|
|
||||||
<div class="laydate-footer-btns">
|
|
||||||
<span lay-type="clear" class="laydate-btns-clear" @click="clear"
|
|
||||||
>清空</span
|
|
||||||
>
|
|
||||||
<span lay-type="now" class="laydate-btns-now" @click="now"
|
|
||||||
>现在</span
|
|
||||||
>
|
|
||||||
<span lay-type="confirm" class="laydate-btns-confirm" @click="ok"
|
|
||||||
>确定</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 月份选择器 -->
|
<!-- 月份选择器 -->
|
||||||
<div class="layui-laydate" v-show="showPane === 'month'">
|
<MonthPanel v-if="!range && showPanel === 'month'"></MonthPanel>
|
||||||
<div class="layui-laydate-main laydate-main-list-0 laydate-ym-show">
|
|
||||||
<div class="layui-laydate-header">
|
|
||||||
<i
|
|
||||||
class="layui-icon laydate-icon laydate-prev-y"
|
|
||||||
@click="changeYearOrMonth('year', -1)"
|
|
||||||
></i
|
|
||||||
>
|
|
||||||
<div class="laydate-set-ym">
|
|
||||||
<span
|
|
||||||
@click="showYearPanel"
|
|
||||||
v-if="showPane === 'date' || showPane === 'datetime'"
|
|
||||||
>{{ currentYear }} 年</span
|
|
||||||
>
|
|
||||||
<span @click="showPane = 'month'"
|
|
||||||
>{{ currentMonth + 1 }} 月</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<i
|
|
||||||
class="layui-icon laydate-icon laydate-next-y"
|
|
||||||
@click="changeYearOrMonth('year', 1)"
|
|
||||||
></i
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="layui-laydate-content" style="height: 220px">
|
|
||||||
<ul class="layui-laydate-list laydate-month-list">
|
|
||||||
<li
|
|
||||||
v-for="item of MONTH_NAME"
|
|
||||||
:key="item"
|
|
||||||
:class="[
|
|
||||||
{ 'layui-this': MONTH_NAME.indexOf(item) === currentMonth },
|
|
||||||
]"
|
|
||||||
@click="handleMonthClick(item)"
|
|
||||||
>
|
|
||||||
{{ item.slice(0, 3) }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-laydate-footer">
|
|
||||||
<span
|
|
||||||
class="layui-laydate-preview"
|
|
||||||
title="当前选中的结果"
|
|
||||||
style="color: rgb(102, 102, 102)"
|
|
||||||
>{{ dateValue }}</span
|
|
||||||
>
|
|
||||||
<div class="laydate-footer-btns">
|
|
||||||
<span lay-type="clear" class="laydate-btns-clear" @click="clear"
|
|
||||||
>清空</span
|
|
||||||
>
|
|
||||||
<span lay-type="now" class="laydate-btns-now" @click="now"
|
|
||||||
>现在</span
|
|
||||||
>
|
|
||||||
<span lay-type="confirm" class="laydate-btns-confirm" @click="ok"
|
|
||||||
>确定</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 时间选择器 -->
|
|
||||||
<div class="layui-laydate" v-if="showPane == 'time'">
|
|
||||||
<div class="layui-laydate-main laydate-main-list-0 laydate-time-show">
|
|
||||||
<div class="layui-laydate-header">
|
|
||||||
<div class="laydate-set-ym">
|
|
||||||
<span class="laydate-time-text">选择时间</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-laydate-content" style="height: 210px">
|
|
||||||
<ul
|
|
||||||
class="layui-laydate-list laydate-time-list"
|
|
||||||
ref="timePanelRef"
|
|
||||||
>
|
|
||||||
<li
|
|
||||||
class="num-list"
|
|
||||||
v-for="item in els"
|
|
||||||
:key="item.type"
|
|
||||||
:data-type="item.type"
|
|
||||||
>
|
|
||||||
<ol class="scroll" @click="choseTime">
|
|
||||||
<li
|
|
||||||
v-for="(it, index) in item.count"
|
|
||||||
:id="item.type + index.toString()"
|
|
||||||
:data-value="index.toString().padStart(2, '0')"
|
|
||||||
:data-type="item.type"
|
|
||||||
:key="it"
|
|
||||||
:class="[
|
|
||||||
'num',
|
|
||||||
index.toString().padStart(2, '0') == hms[item.type]
|
|
||||||
? 'layui-this'
|
|
||||||
: '',
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
{{ index.toString().padStart(2, "0") }}
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-laydate-footer">
|
|
||||||
<span
|
|
||||||
@click="showPane = 'date'"
|
|
||||||
v-if="type != 'time'"
|
|
||||||
class="laydate-btns-time"
|
|
||||||
>返回日期</span
|
|
||||||
>
|
|
||||||
<div class="laydate-footer-btns">
|
|
||||||
<span lay-type="clear" class="laydate-btns-clear" @click="clear"
|
|
||||||
>清空</span
|
|
||||||
>
|
|
||||||
<span lay-type="now" class="laydate-btns-now" @click="now"
|
|
||||||
>现在</span
|
|
||||||
>
|
|
||||||
<span lay-type="confirm" class="laydate-btns-confirm" @click="ok"
|
|
||||||
>确定</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</lay-dropdown>
|
</lay-dropdown>
|
||||||
</div>
|
</div>
|
||||||
@ -290,16 +32,11 @@ import { LayIcon } from "@layui/icons-vue";
|
|||||||
import LayInput from "../input/index.vue";
|
import LayInput from "../input/index.vue";
|
||||||
import LayDropdown from "../dropdown/index.vue";
|
import LayDropdown from "../dropdown/index.vue";
|
||||||
import { getDayLength, getYears, getMonth, getYear, getDay } from "./day";
|
import { getDayLength, getYears, getMonth, getYear, getDay } from "./day";
|
||||||
import {
|
import { ref, watch, computed, defineProps, defineEmits, onMounted, nextTick, reactive, provide } from "vue";
|
||||||
ref,
|
import DatePanel from './components/DatePanel.vue';
|
||||||
watch,
|
import TimePanel from './components/TimePanel.vue';
|
||||||
computed,
|
import YearPanel from './components/YearPanel.vue';
|
||||||
defineProps,
|
import MonthPanel from './components/MonthPanel.vue';
|
||||||
defineEmits,
|
|
||||||
onMounted,
|
|
||||||
nextTick,
|
|
||||||
} from "vue";
|
|
||||||
import { anyTypeAnnotation } from "@babel/types";
|
|
||||||
|
|
||||||
export interface LayDatePickerProps {
|
export interface LayDatePickerProps {
|
||||||
type?: "date" | "datetime" | "year" | "time" | "month" | "yearmonth";
|
type?: "date" | "datetime" | "year" | "time" | "month" | "yearmonth";
|
||||||
@ -310,6 +47,7 @@ export interface LayDatePickerProps {
|
|||||||
name?: string;
|
name?: string;
|
||||||
max?: string;
|
max?: string;
|
||||||
min?: string;
|
min?: string;
|
||||||
|
range?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<LayDatePickerProps>(), {
|
const props = withDefaults(defineProps<LayDatePickerProps>(), {
|
||||||
@ -317,26 +55,13 @@ const props = withDefaults(defineProps<LayDatePickerProps>(), {
|
|||||||
type: "date",
|
type: "date",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
simple: false,
|
simple: false,
|
||||||
|
range: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const dropdownRef = ref(null);
|
const dropdownRef = ref(null);
|
||||||
const $emits = defineEmits(["update:modelValue"]);
|
const $emits = defineEmits(["update:modelValue"]);
|
||||||
|
|
||||||
const WEEK_NAME = ["日", "一", "二", "三", "四", "五", "六"];
|
|
||||||
const MONTH_NAME = [
|
|
||||||
"1月",
|
|
||||||
"2月",
|
|
||||||
"3月",
|
|
||||||
"4月",
|
|
||||||
"5月",
|
|
||||||
"6月",
|
|
||||||
"7月",
|
|
||||||
"8月",
|
|
||||||
"9月",
|
|
||||||
"10月",
|
|
||||||
"11月",
|
|
||||||
"12月",
|
|
||||||
];
|
|
||||||
|
|
||||||
const hms = ref({
|
const hms = ref({
|
||||||
hh: dayjs(props.modelValue).hour(),
|
hh: dayjs(props.modelValue).hour(),
|
||||||
@ -344,31 +69,30 @@ const hms = ref({
|
|||||||
ss: dayjs(props.modelValue).second(),
|
ss: dayjs(props.modelValue).second(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const els = [
|
|
||||||
{ count: 24, type: "hh" },
|
|
||||||
{ count: 60, type: "mm" },
|
|
||||||
{ count: 60, type: "ss" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const currentYear = ref(getYear(props.modelValue));
|
const currentYear = ref(getYear(props.modelValue));
|
||||||
const currentMonth = ref(getMonth(props.modelValue));
|
const currentMonth = ref(getMonth(props.modelValue));
|
||||||
const currentDay = ref<number>(getDay(props.modelValue));
|
const currentDay = ref<number>(getDay(props.modelValue));
|
||||||
|
|
||||||
const yearList = ref<number[]>(getYears());
|
const yearList = ref<number[]>(getYears());
|
||||||
const dateList = ref<any[]>([]);
|
const dateList = ref<any[]>([]);
|
||||||
const showPane = ref("date");
|
const dateListNext = ref<any[]>([]);
|
||||||
|
const showPanel = ref("date");
|
||||||
|
|
||||||
const yearmonthScrollRef = ref();
|
const yearmonthScrollRef = ref()
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.type,
|
() => props.type,
|
||||||
() => {
|
() => {
|
||||||
showPane.value = props.type;
|
showPanel.value = props.type;
|
||||||
|
if (props.type === 'yearmonth') {
|
||||||
|
showPanel.value = 'year';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
//初始值为空时的容错
|
||||||
if (currentDay.value == -1) {
|
if (currentDay.value == -1) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
now();
|
now();
|
||||||
@ -376,21 +100,29 @@ onMounted(() => {
|
|||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
let modelValue = props.modelValue;
|
let modelValue = props.modelValue;
|
||||||
if (modelValue.length === 8) {
|
if (modelValue.length === 8) { //dayjs 解析时间容错
|
||||||
//dayjs 解析时间容错
|
modelValue = '1970-01-01 ' + modelValue;
|
||||||
modelValue = "1970-01-01 " + modelValue;
|
|
||||||
}
|
}
|
||||||
hms.value.hh = dayjs(modelValue).hour();
|
hms.value.hh = dayjs(modelValue).hour();
|
||||||
hms.value.mm = dayjs(modelValue).minute();
|
hms.value.mm = dayjs(modelValue).minute();
|
||||||
hms.value.ss = dayjs(modelValue).second();
|
hms.value.ss = dayjs(modelValue).second();
|
||||||
|
getDateValue()
|
||||||
});
|
});
|
||||||
|
|
||||||
// 计算结果日期
|
// 计算结果日期
|
||||||
const dateValue = computed<string>(() => {
|
const dateValue = ref('')
|
||||||
if (currentDay.value === -1) {
|
const getDateValue = (checkCurrentDay = true) => {
|
||||||
$emits("update:modelValue", "");
|
if (checkCurrentDay) {
|
||||||
return "";
|
if (currentDay.value === -1) {
|
||||||
|
$emits("update:modelValue", "");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (currentDay.value === -1) {
|
||||||
|
currentDay.value = new Date(new Date().toDateString()).getTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let dayjsVal;
|
let dayjsVal;
|
||||||
let dayjsObj = dayjs(currentDay.value)
|
let dayjsObj = dayjs(currentDay.value)
|
||||||
.hour(hms.value.hh)
|
.hour(hms.value.hh)
|
||||||
@ -419,77 +151,14 @@ const dateValue = computed<string>(() => {
|
|||||||
dayjsVal = dayjsObj.format();
|
dayjsVal = dayjsObj.format();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
dateValue.value = dayjsVal;
|
||||||
$emits("update:modelValue", dayjsVal);
|
$emits("update:modelValue", dayjsVal);
|
||||||
if (props.simple && unWatch.value) {
|
|
||||||
ok();
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
unWatch.value = false;
|
|
||||||
}, 0);
|
|
||||||
return dayjsVal;
|
return dayjsVal;
|
||||||
});
|
|
||||||
|
|
||||||
// 设置日期列表
|
|
||||||
const setDateList = (year: number, month: number) => {
|
|
||||||
const curDays = getDayLength(year, month); // 当月天数
|
|
||||||
const prevDays = getDayLength(year, month - 1); // 上月天数
|
|
||||||
const curFirstDayWeek = new Date(year, month, 1).getDay(); // 当月第一天星期几
|
|
||||||
const list: any[] = [];
|
|
||||||
// 填充上月天数
|
|
||||||
for (let i = prevDays - curFirstDayWeek + 1; i <= prevDays; i++) {
|
|
||||||
list.push({
|
|
||||||
day: i,
|
|
||||||
value: +new Date(year, month - 1, i),
|
|
||||||
isRange: false,
|
|
||||||
isSelected: false,
|
|
||||||
type: "prev",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 填充当月天数
|
|
||||||
for (let i = 1; i <= curDays; i++) {
|
|
||||||
list.push({
|
|
||||||
day: i,
|
|
||||||
value: +new Date(year, month, i),
|
|
||||||
isRange: false,
|
|
||||||
isSelected: false,
|
|
||||||
type: "current",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 填充下月天数
|
|
||||||
const nextDays = 7 - (list.length % 7);
|
|
||||||
if (nextDays !== 7) {
|
|
||||||
for (let i = 1; i <= nextDays; i++) {
|
|
||||||
list.push({
|
|
||||||
day: i,
|
|
||||||
value: +new Date(year, month + 1, i),
|
|
||||||
isRange: false,
|
|
||||||
isSelected: false,
|
|
||||||
type: "next",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dateList.value = list;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 监听年月, 刷新日期
|
|
||||||
watch(
|
|
||||||
[currentYear, currentMonth],
|
|
||||||
() => {
|
|
||||||
setDateList(currentYear.value, currentMonth.value);
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
const unWatch = ref(true);
|
|
||||||
watch(
|
|
||||||
() => props.modelValue,
|
|
||||||
() => {
|
|
||||||
if (!unWatch.value) {
|
|
||||||
currentDay.value = new Date(props.modelValue).getTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// 确认事件
|
// 确认事件
|
||||||
const ok = () => {
|
const ok = () => {
|
||||||
|
getDateValue(false)
|
||||||
if (dropdownRef.value)
|
if (dropdownRef.value)
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
dropdownRef.value.hide();
|
dropdownRef.value.hide();
|
||||||
@ -497,7 +166,6 @@ const ok = () => {
|
|||||||
|
|
||||||
// 现在时间
|
// 现在时间
|
||||||
const now = () => {
|
const now = () => {
|
||||||
unWatch.value = true;
|
|
||||||
currentDay.value = dayjs().valueOf();
|
currentDay.value = dayjs().valueOf();
|
||||||
hms.value.hh = dayjs().hour();
|
hms.value.hh = dayjs().hour();
|
||||||
hms.value.mm = dayjs().minute();
|
hms.value.mm = dayjs().minute();
|
||||||
@ -506,104 +174,65 @@ const now = () => {
|
|||||||
|
|
||||||
// 清空日期
|
// 清空日期
|
||||||
const clear = () => {
|
const clear = () => {
|
||||||
unWatch.value = true;
|
|
||||||
currentDay.value = -1;
|
currentDay.value = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 切换年月
|
//simple
|
||||||
const changeYearOrMonth = (type: "year" | "month", num: number) => {
|
watch(currentDay, () => {
|
||||||
if (type === "year") {
|
if (props.simple) {
|
||||||
currentYear.value += num;
|
getDateValue();
|
||||||
} else {
|
ok();
|
||||||
let month = currentMonth.value + num;
|
|
||||||
if (month > 11) {
|
|
||||||
month = 0;
|
|
||||||
currentYear.value++;
|
|
||||||
} else if (month < 0) {
|
|
||||||
month = 11;
|
|
||||||
currentYear.value--;
|
|
||||||
}
|
|
||||||
currentMonth.value = month;
|
|
||||||
}
|
}
|
||||||
};
|
})
|
||||||
|
watch(currentMonth, () => {
|
||||||
// 显示年列表面板
|
if (props.simple && props.type !== 'date') {
|
||||||
const showYearPanel = () => {
|
getDateValue();
|
||||||
showPane.value = "year";
|
ok();
|
||||||
};
|
|
||||||
|
|
||||||
// 点击年份
|
|
||||||
const handleYearClick = (item: any) => {
|
|
||||||
unWatch.value = true;
|
|
||||||
currentYear.value = item;
|
|
||||||
if (props.type === "year") {
|
|
||||||
currentDay.value = dayjs().year(item).valueOf();
|
|
||||||
} else if (props.type === "yearmonth") {
|
|
||||||
currentDay.value = dayjs().year(item).valueOf();
|
|
||||||
showPane.value = "month";
|
|
||||||
} else {
|
|
||||||
showPane.value = "date";
|
|
||||||
}
|
}
|
||||||
};
|
})
|
||||||
|
watch(currentYear, () => {
|
||||||
// 点击月份
|
if (props.simple && props.type !== 'date') {
|
||||||
const handleMonthClick = (item: any) => {
|
getDateValue();
|
||||||
unWatch.value = true;
|
ok();
|
||||||
currentMonth.value = MONTH_NAME.indexOf(item);
|
|
||||||
if (props.type === "month") {
|
|
||||||
currentDay.value = dayjs(currentDay.value)
|
|
||||||
.month(MONTH_NAME.indexOf(item))
|
|
||||||
.valueOf();
|
|
||||||
} else if (props.type === "yearmonth") {
|
|
||||||
currentDay.value = dayjs(currentDay.value)
|
|
||||||
.month(MONTH_NAME.indexOf(item))
|
|
||||||
.valueOf();
|
|
||||||
} else {
|
|
||||||
showPane.value = "date";
|
|
||||||
}
|
}
|
||||||
};
|
})
|
||||||
|
|
||||||
// 点击日期
|
provide('datePicker', {
|
||||||
const handleDayClick = (item: any) => {
|
currentYear: currentYear,
|
||||||
unWatch.value = true;
|
currentMonth: currentMonth,
|
||||||
currentDay.value = item.value;
|
currentDay: currentDay,
|
||||||
if (item.type !== "current") {
|
dateValue: dateValue,
|
||||||
currentMonth.value =
|
type: props.type,
|
||||||
item.type === "prev" ? currentMonth.value - 1 : currentMonth.value + 1;
|
showPanel: showPanel,
|
||||||
}
|
dateList: dateList,
|
||||||
};
|
yearList: yearList,
|
||||||
|
hms: hms,
|
||||||
// 点击时间 - hms
|
clear: () => clear(),
|
||||||
const choseTime = (e: any) => {
|
now: () => now(),
|
||||||
unWatch.value = true;
|
ok: () => ok(),
|
||||||
if (e.target.nodeName == "LI") {
|
getDateValue: () => getDateValue,
|
||||||
let { value, type } = e.target.dataset;
|
range: props.range
|
||||||
hms.value[type as keyof typeof hms.value] = value;
|
});
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const openDropDown = () => {
|
const openDropDown = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (showPane.value == "year" || showPane.value == "yearmonth") {
|
// if (showPanel.value == 'year' || showPanel.value == 'yearmonth') {
|
||||||
let scrollTop = 0;
|
// let scrollTop = 0;
|
||||||
for (const child of yearmonthScrollRef.value.firstElementChild
|
// for (const child of yearmonthScrollRef.value.firstElementChild.childNodes) {
|
||||||
.childNodes) {
|
// if (child.classList && child.classList.contains('layui-this')) {
|
||||||
if (child.classList && child.classList.contains("layui-this")) {
|
// scrollTop = child.offsetTop - (yearmonthScrollRef.value.offsetHeight - child.offsetHeight) / 2;
|
||||||
scrollTop =
|
// break;
|
||||||
child.offsetTop -
|
// }
|
||||||
(yearmonthScrollRef.value.offsetHeight - child.offsetHeight) / 2;
|
// }
|
||||||
break;
|
// yearmonthScrollRef.value.scrollTo(0, scrollTop)
|
||||||
}
|
// } else if (showPanel.value == 'time') {
|
||||||
}
|
// scrollToCurrentTime()
|
||||||
yearmonthScrollRef.value.scrollTo(0, scrollTop);
|
// }
|
||||||
} else if (showPane.value == "time") {
|
})
|
||||||
scrollToCurrentTime();
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//时间定位
|
//时间定位
|
||||||
const timePanelRef = ref();
|
const timePanelRef = ref()
|
||||||
const scrollToCurrentTime = () => {
|
const scrollToCurrentTime = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
timePanelRef.value.childNodes.forEach((element: HTMLElement) => {
|
timePanelRef.value.childNodes.forEach((element: HTMLElement) => {
|
||||||
@ -626,6 +255,46 @@ const scrollToCurrentTime = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
|
//范围选择
|
||||||
|
const rangeValue = reactive({
|
||||||
|
first: '', last: '', hover: ''
|
||||||
|
})
|
||||||
|
const dayItemMouseEnter = (event: MouseEvent, item: any) => {
|
||||||
|
if (!props.range) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!rangeValue.first) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (item.type !== 'current') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rangeValue.hover = (event.target as HTMLElement).dataset.unix as string
|
||||||
|
}
|
||||||
|
const ifHasRangeHoverClass = computed(() => {
|
||||||
|
return function (item: any) {
|
||||||
|
if (!props.range) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!rangeValue.first) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (item.type !== 'current') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (item.value == parseInt(rangeValue.first) || item.value == parseInt(rangeValue.last)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let hover = rangeValue.last ? rangeValue.last : rangeValue.hover;
|
||||||
|
let max = rangeValue.first > hover ? rangeValue.first : hover;
|
||||||
|
let min = rangeValue.first < hover ? rangeValue.first : hover
|
||||||
|
if (item.value >= parseInt(min) && item.value <= parseInt(max)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -1 +1,19 @@
|
|||||||
|
import { Ref } from "vue";
|
||||||
|
|
||||||
export type DatePickerType = "date" | "datetime" | "year" | "time" | "month";
|
export type DatePickerType = "date" | "datetime" | "year" | "time" | "month";
|
||||||
|
|
||||||
|
export type provideType={
|
||||||
|
currentYear:Ref,
|
||||||
|
currentMonth:Ref,
|
||||||
|
currentDay:Ref,
|
||||||
|
dateValue:Ref,
|
||||||
|
dateList:Ref,
|
||||||
|
yearList:Ref,
|
||||||
|
hms:Ref,
|
||||||
|
type:string,
|
||||||
|
showPanel:Ref,
|
||||||
|
clear:Function,
|
||||||
|
now:Function,
|
||||||
|
ok:Function,
|
||||||
|
range:boolean,
|
||||||
|
}
|
@ -193,10 +193,14 @@ export default {
|
|||||||
::: title 一次性选择
|
::: title 一次性选择
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: demo 只需要点击一次后自动关闭,无需点击确认按钮
|
::: demo 只需要点击一次后自动关闭,无需点击确认按钮,仅在type等于`year`、`month`、`date`时有效
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-date-picker v-model="endTime7" simple></lay-date-picker>
|
<div style="display:flex">
|
||||||
|
<lay-date-picker v-model="endTime7" simple type="year"></lay-date-picker>
|
||||||
|
<lay-date-picker v-model="endTime7" simple type="month" style="margin:0 10px"></lay-date-picker>
|
||||||
|
<lay-date-picker v-model="endTime7" simple type="date"></lay-date-picker>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
Loading…
Reference in New Issue
Block a user