diff --git a/package/component/src/component/datePicker/components/DatePanel.vue b/package/component/src/component/datePicker/components/DatePanel.vue
new file mode 100644
index 00000000..9a08e15f
--- /dev/null
+++ b/package/component/src/component/datePicker/components/DatePanel.vue
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+
+
+ {{ item }} |
+
+
+
+
+
+
+ {{ item.day }}
+ |
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package/component/src/component/datePicker/components/MonthPanel.vue b/package/component/src/component/datePicker/components/MonthPanel.vue
new file mode 100644
index 00000000..68f3a357
--- /dev/null
+++ b/package/component/src/component/datePicker/components/MonthPanel.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+ -
+ {{ item.slice(0, 3) }}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package/component/src/component/datePicker/components/PanelFoot.vue b/package/component/src/component/datePicker/components/PanelFoot.vue
new file mode 100644
index 00000000..05c2ae8e
--- /dev/null
+++ b/package/component/src/component/datePicker/components/PanelFoot.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/package/component/src/component/datePicker/components/TimePanel.vue b/package/component/src/component/datePicker/components/TimePanel.vue
new file mode 100644
index 00000000..867d794f
--- /dev/null
+++ b/package/component/src/component/datePicker/components/TimePanel.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+ -
+
+ -
+ {{ index.toString().padStart(2, "0") }}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package/component/src/component/datePicker/components/YearPanel.vue b/package/component/src/component/datePicker/components/YearPanel.vue
new file mode 100644
index 00000000..cdce3c82
--- /dev/null
+++ b/package/component/src/component/datePicker/components/YearPanel.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/package/component/src/component/datePicker/day.ts b/package/component/src/component/datePicker/day.ts
index 9e46ecc4..3c66e814 100644
--- a/package/component/src/component/datePicker/day.ts
+++ b/package/component/src/component/datePicker/day.ts
@@ -52,4 +52,47 @@ const getDayLength = (year: number, month: number): number => {
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 };
diff --git a/package/component/src/component/datePicker/index.less b/package/component/src/component/datePicker/index.less
index cc81a475..06d3546a 100644
--- a/package/component/src/component/datePicker/index.less
+++ b/package/component/src/component/datePicker/index.less
@@ -459,3 +459,10 @@ html #layuicss-laydate {
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;
+}
\ No newline at end of file
diff --git a/package/component/src/component/datePicker/index.vue b/package/component/src/component/datePicker/index.vue
index ae7a5ca4..6c31ef58 100644
--- a/package/component/src/component/datePicker/index.vue
+++ b/package/component/src/component/datePicker/index.vue
@@ -1,277 +1,19 @@
-
+
-
-
-
-
-
-
-
- {{ item }} |
-
-
-
-
-
-
- {{ item.day }}
- |
-
-
-
-
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
- -
- {{ item.slice(0, 3) }}
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- -
- {{ index.toString().padStart(2, "0") }}
-
-
-
-
-
-
-
-
+
@@ -290,16 +32,11 @@ import { LayIcon } from "@layui/icons-vue";
import LayInput from "../input/index.vue";
import LayDropdown from "../dropdown/index.vue";
import { getDayLength, getYears, getMonth, getYear, getDay } from "./day";
-import {
- ref,
- watch,
- computed,
- defineProps,
- defineEmits,
- onMounted,
- nextTick,
-} from "vue";
-import { anyTypeAnnotation } from "@babel/types";
+import { ref, watch, computed, defineProps, defineEmits, onMounted, nextTick, reactive, provide } from "vue";
+import DatePanel from './components/DatePanel.vue';
+import TimePanel from './components/TimePanel.vue';
+import YearPanel from './components/YearPanel.vue';
+import MonthPanel from './components/MonthPanel.vue';
export interface LayDatePickerProps {
type?: "date" | "datetime" | "year" | "time" | "month" | "yearmonth";
@@ -310,6 +47,7 @@ export interface LayDatePickerProps {
name?: string;
max?: string;
min?: string;
+ range?: boolean
}
const props = withDefaults(defineProps(), {
@@ -317,26 +55,13 @@ const props = withDefaults(defineProps(), {
type: "date",
disabled: false,
simple: false,
+ range: false
});
const dropdownRef = ref(null);
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({
hh: dayjs(props.modelValue).hour(),
@@ -344,31 +69,30 @@ const hms = ref({
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 currentMonth = ref(getMonth(props.modelValue));
const currentDay = ref(getDay(props.modelValue));
const yearList = ref(getYears());
const dateList = ref([]);
-const showPane = ref("date");
+const dateListNext = ref([]);
+const showPanel = ref("date");
-const yearmonthScrollRef = ref();
+const yearmonthScrollRef = ref()
watch(
() => props.type,
() => {
- showPane.value = props.type;
+ showPanel.value = props.type;
+ if (props.type === 'yearmonth') {
+ showPanel.value = 'year';
+ }
},
{ immediate: true }
);
onMounted(() => {
+ //初始值为空时的容错
if (currentDay.value == -1) {
setTimeout(() => {
now();
@@ -376,21 +100,29 @@ onMounted(() => {
}, 0);
}
let modelValue = props.modelValue;
- if (modelValue.length === 8) {
- //dayjs 解析时间容错
- modelValue = "1970-01-01 " + modelValue;
+ if (modelValue.length === 8) { //dayjs 解析时间容错
+ modelValue = '1970-01-01 ' + modelValue;
}
hms.value.hh = dayjs(modelValue).hour();
hms.value.mm = dayjs(modelValue).minute();
hms.value.ss = dayjs(modelValue).second();
+ getDateValue()
});
// 计算结果日期
-const dateValue = computed(() => {
- if (currentDay.value === -1) {
- $emits("update:modelValue", "");
- return "";
+const dateValue = ref('')
+const getDateValue = (checkCurrentDay = true) => {
+ if (checkCurrentDay) {
+ if (currentDay.value === -1) {
+ $emits("update:modelValue", "");
+ return "";
+ }
+ } else {
+ if (currentDay.value === -1) {
+ currentDay.value = new Date(new Date().toDateString()).getTime();
+ }
}
+
let dayjsVal;
let dayjsObj = dayjs(currentDay.value)
.hour(hms.value.hh)
@@ -419,77 +151,14 @@ const dateValue = computed(() => {
dayjsVal = dayjsObj.format();
break;
}
+ dateValue.value = dayjsVal;
$emits("update:modelValue", dayjsVal);
- if (props.simple && unWatch.value) {
- ok();
- }
- setTimeout(() => {
- unWatch.value = false;
- }, 0);
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 = () => {
+ getDateValue(false)
if (dropdownRef.value)
// @ts-ignore
dropdownRef.value.hide();
@@ -497,7 +166,6 @@ const ok = () => {
// 现在时间
const now = () => {
- unWatch.value = true;
currentDay.value = dayjs().valueOf();
hms.value.hh = dayjs().hour();
hms.value.mm = dayjs().minute();
@@ -506,104 +174,65 @@ const now = () => {
// 清空日期
const clear = () => {
- unWatch.value = true;
currentDay.value = -1;
};
-// 切换年月
-const changeYearOrMonth = (type: "year" | "month", num: number) => {
- if (type === "year") {
- currentYear.value += num;
- } else {
- let month = currentMonth.value + num;
- if (month > 11) {
- month = 0;
- currentYear.value++;
- } else if (month < 0) {
- month = 11;
- currentYear.value--;
- }
- currentMonth.value = month;
+//simple
+watch(currentDay, () => {
+ if (props.simple) {
+ getDateValue();
+ ok();
}
-};
-
-// 显示年列表面板
-const showYearPanel = () => {
- showPane.value = "year";
-};
-
-// 点击年份
-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(currentMonth, () => {
+ if (props.simple && props.type !== 'date') {
+ getDateValue();
+ ok();
}
-};
-
-// 点击月份
-const handleMonthClick = (item: any) => {
- unWatch.value = true;
- 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";
+})
+watch(currentYear, () => {
+ if (props.simple && props.type !== 'date') {
+ getDateValue();
+ ok();
}
-};
+})
-// 点击日期
-const handleDayClick = (item: any) => {
- unWatch.value = true;
- currentDay.value = item.value;
- if (item.type !== "current") {
- currentMonth.value =
- item.type === "prev" ? currentMonth.value - 1 : currentMonth.value + 1;
- }
-};
-
-// 点击时间 - hms
-const choseTime = (e: any) => {
- unWatch.value = true;
- if (e.target.nodeName == "LI") {
- let { value, type } = e.target.dataset;
- hms.value[type as keyof typeof hms.value] = value;
- }
-};
+provide('datePicker', {
+ currentYear: currentYear,
+ currentMonth: currentMonth,
+ currentDay: currentDay,
+ dateValue: dateValue,
+ type: props.type,
+ showPanel: showPanel,
+ dateList: dateList,
+ yearList: yearList,
+ hms: hms,
+ clear: () => clear(),
+ now: () => now(),
+ ok: () => ok(),
+ getDateValue: () => getDateValue,
+ range: props.range
+});
const openDropDown = () => {
nextTick(() => {
- if (showPane.value == "year" || showPane.value == "yearmonth") {
- let scrollTop = 0;
- for (const child of yearmonthScrollRef.value.firstElementChild
- .childNodes) {
- if (child.classList && child.classList.contains("layui-this")) {
- scrollTop =
- child.offsetTop -
- (yearmonthScrollRef.value.offsetHeight - child.offsetHeight) / 2;
- break;
- }
- }
- yearmonthScrollRef.value.scrollTo(0, scrollTop);
- } else if (showPane.value == "time") {
- scrollToCurrentTime();
- }
- });
-};
+ // if (showPanel.value == 'year' || showPanel.value == 'yearmonth') {
+ // let scrollTop = 0;
+ // for (const child of yearmonthScrollRef.value.firstElementChild.childNodes) {
+ // if (child.classList && child.classList.contains('layui-this')) {
+ // scrollTop = child.offsetTop - (yearmonthScrollRef.value.offsetHeight - child.offsetHeight) / 2;
+ // break;
+ // }
+ // }
+ // yearmonthScrollRef.value.scrollTo(0, scrollTop)
+ // } else if (showPanel.value == 'time') {
+ // scrollToCurrentTime()
+ // }
+ })
+}
//时间定位
-const timePanelRef = ref();
+const timePanelRef = ref()
const scrollToCurrentTime = () => {
nextTick(() => {
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
+ }
+})
diff --git a/package/component/src/component/datePicker/interface.ts b/package/component/src/component/datePicker/interface.ts
index 28053d5c..e81f4fed 100644
--- a/package/component/src/component/datePicker/interface.ts
+++ b/package/component/src/component/datePicker/interface.ts
@@ -1 +1,19 @@
+import { Ref } from "vue";
+
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,
+}
\ No newline at end of file
diff --git a/package/document-component/src/document/zh-CN/components/datePicker.md b/package/document-component/src/document/zh-CN/components/datePicker.md
index 4b47c993..d56be566 100644
--- a/package/document-component/src/document/zh-CN/components/datePicker.md
+++ b/package/document-component/src/document/zh-CN/components/datePicker.md
@@ -193,10 +193,14 @@ export default {
::: title 一次性选择
:::
-::: demo 只需要点击一次后自动关闭,无需点击确认按钮
+::: demo 只需要点击一次后自动关闭,无需点击确认按钮,仅在type等于`year`、`month`、`date`时有效
-
+
+
+
+
+