Skip to content

Commit a910d0f

Browse files
committed
refactor(YearMonthPicker): 添加js逻辑
1 parent 4e3ee69 commit a910d0f

File tree

2 files changed

+246
-1
lines changed

2 files changed

+246
-1
lines changed

src/calendar/Calendar.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ export const calendarProps = {
6868
type: Function,
6969
default: () => false,
7070
},
71+
disabledTime: {
72+
type: Function,
73+
default: () => false,
74+
},
7175
lang: makeStringProp<LangType>('CN'),
7276
scrollChangeDate: truthProp,
7377
minuteStep: makeNumberProp(1),
@@ -558,6 +562,7 @@ export default defineComponent({
558562
defaultTime={currDateTime.value}
559563
calendarDate={checkedDate.value}
560564
onChange={timeChange}
565+
{...pick(props, ['minuteStep', 'disabledTime'])}
561566
/>
562567
);
563568
}

src/calendar/CalendarYearMonth.tsx

+241-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1-
import { ExtractPropTypes, type PropType } from 'vue';
1+
import {
2+
computed,
3+
defineComponent,
4+
ExtractPropTypes,
5+
ref,
6+
watch,
7+
type PropType,
8+
} from 'vue';
9+
import { ScorllDireType } from './components/scroll-container';
10+
import languageUtil, { LanguageEntityType, LanguageType } from './language';
211
import type { CalendarDateType, DisabledScrollType, LangType } from './types';
312
import {
13+
isDateInRange,
414
makeDateProp,
515
makeNumberProp,
616
makeStringProp,
@@ -35,3 +45,233 @@ export const calendarYearMonthProps = {
3545
export type CalendarYearMonthPropsType = ExtractPropTypes<
3646
typeof calendarYearMonthProps
3747
>;
48+
49+
type YearRangeType = { s: number; e: number };
50+
51+
export default defineComponent({
52+
name: 'CalendarYearMonth',
53+
54+
props: calendarYearMonthProps,
55+
56+
emits: ['click', 'slidechange', 'touchstart', 'touchmove', 'touchend'],
57+
58+
setup(props, { emit }) {
59+
const language = ref({} as LanguageEntityType);
60+
const yearRange = ref(10);
61+
const disabledScrollDirec = ref<DisabledScrollType>(false);
62+
const yearMonthShow = ref<(number | string | YearRangeType)[][]>([]);
63+
64+
const lang = props.lang.toUpperCase() as LanguageType;
65+
language.value = languageUtil[lang];
66+
67+
const itemHeight = computed(
68+
() => (props.calendarContentHeight - props.calendarTitleHeight) / 4
69+
);
70+
71+
const initYear = (year: number) => {
72+
const yearArr = [];
73+
const currYear = `${year || props.calendarDate.year}`;
74+
const yearStart = parseInt(currYear.substring(0, 3) + '0', 10);
75+
for (let i = 0; i <= yearRange.value; i++) {
76+
yearArr.push(yearStart + i);
77+
}
78+
yearArr.unshift(yearStart - 1);
79+
80+
return yearArr;
81+
};
82+
83+
const initYearRange = (year: number) => {
84+
const yearRangeArr = [];
85+
const currYear = `${year || props.calendarDate.year}`;
86+
const yearStart = parseInt(currYear.substring(0, 2) + '00', 10);
87+
for (let i = 0; i <= yearRange.value; i++) {
88+
yearRangeArr.push({ s: yearStart + i * 10, e: yearStart + i * 10 + 9 });
89+
}
90+
yearRangeArr.unshift({ s: yearStart - 10, e: yearStart - 1 });
91+
92+
return yearRangeArr;
93+
};
94+
95+
const getThreeYearArr = (year = props.calendarDate.year) => {
96+
const yearStr = year + '';
97+
const yearStart = yearStr.substring(0, 3);
98+
const yearStartLast = parseInt(parseInt(yearStart, 10) - 1 + '0', 10);
99+
const yearStartCurr = parseInt(yearStart + '0', 10);
100+
const yearStartNext = parseInt(parseInt(yearStart, 10) + 1 + '0', 10);
101+
102+
return [
103+
initYear(yearStartLast),
104+
initYear(yearStartCurr),
105+
initYear(yearStartNext),
106+
];
107+
};
108+
109+
const getThreeYearRangeArr = (year = props.calendarDate.year) => {
110+
const yearStr = year + '';
111+
const yearStart = yearStr.substring(0, 2);
112+
const yearStartLast = parseInt(parseInt(yearStart, 10) - 1 + '00', 10);
113+
const yearStartCurr = parseInt(yearStart + '00', 10);
114+
const yearStartNext = parseInt(parseInt(yearStart, 10) + 1 + '00', 10);
115+
116+
return [
117+
initYearRange(yearStartLast),
118+
initYearRange(yearStartCurr),
119+
initYearRange(yearStartNext),
120+
];
121+
};
122+
123+
const getNextOpitonData = () => {
124+
if (props.type === 'year') {
125+
const year = yearMonthShow.value[2][1] as number;
126+
yearMonthShow.value = getThreeYearArr(year);
127+
} else if (props.type === 'yearRange') {
128+
const value = yearMonthShow.value[2][1] as YearRangeType;
129+
const year = value.s;
130+
yearMonthShow.value = getThreeYearRangeArr(year);
131+
}
132+
};
133+
134+
const getLastOptionData = () => {
135+
if (props.type === 'year') {
136+
const year = yearMonthShow.value[0][1] as number;
137+
yearMonthShow.value = getThreeYearArr(year);
138+
} else if (props.type === 'yearRange') {
139+
const value = yearMonthShow.value[0][1] as YearRangeType;
140+
const year = value.s;
141+
yearMonthShow.value = getThreeYearRangeArr(year);
142+
}
143+
};
144+
145+
const slideChange = (direc: ScorllDireType) => {
146+
if (direc === 'left') {
147+
getNextOpitonData();
148+
} else if (direc === 'right') {
149+
getLastOptionData();
150+
}
151+
152+
emit('slidechange', direc);
153+
};
154+
155+
const getRangeYear = (date: YearRangeType) => {
156+
const yearStart = date.s;
157+
const yearEnd = date.e;
158+
const yearArr = [];
159+
160+
for (let i = yearStart; i <= yearEnd; i++) {
161+
yearArr.push(i);
162+
}
163+
164+
return yearArr;
165+
};
166+
167+
const isDisabled = (date: YearRangeType & number, index: number) => {
168+
let fDate = new Date();
169+
170+
if (props.type === 'month') {
171+
fDate = new Date(
172+
`${props.calendarDate.year}/${index + 1}/${props.calendarDate.day}`
173+
);
174+
} else if (props.type === 'year') {
175+
fDate = new Date(
176+
`${date}/${props.calendarDate.month + 1}/${props.calendarDate.day}`
177+
);
178+
} else if (props.type === 'yearRange') {
179+
const yearArr = getRangeYear(date);
180+
return yearArr.every((year) => {
181+
fDate = new Date(
182+
`${year}/${props.calendarDate.month + 1}/${props.calendarDate.day}`
183+
);
184+
return (
185+
props.disabledDate(fDate) ||
186+
!isDateInRange(fDate, props.minDate, props.maxDate)
187+
);
188+
});
189+
}
190+
191+
return (
192+
props.disabledDate(fDate) ||
193+
!isDateInRange(fDate, props.minDate, props.maxDate)
194+
);
195+
};
196+
197+
const dateClick = (date: YearRangeType & number, index: number) => {
198+
if (!date) return; // fix:1月无法选中
199+
if (isDisabled(date, index)) return;
200+
201+
let checkedDate = { ...props.calendarDate, type: props.type };
202+
if (props.type === 'month') {
203+
checkedDate = {
204+
...checkedDate,
205+
month: index,
206+
};
207+
}
208+
if (props.type === 'year') {
209+
checkedDate = {
210+
...checkedDate,
211+
year: date,
212+
};
213+
}
214+
if (props.type === 'yearRange') {
215+
const yearArr = getRangeYear(date);
216+
checkedDate = {
217+
...checkedDate,
218+
year: yearArr.includes(checkedDate.year) ? checkedDate.year : date.s,
219+
};
220+
}
221+
222+
emit('click', checkedDate);
223+
};
224+
225+
const isChecked = (date: YearRangeType & number, index: number) => {
226+
if (props.type === 'month') {
227+
return index === props.calendarDate.month;
228+
}
229+
if (props.type === 'year') {
230+
return date === props.calendarDate.year;
231+
}
232+
if (props.type === 'yearRange') {
233+
return (
234+
date.s <= props.calendarDate.year && date.e >= props.calendarDate.year
235+
);
236+
}
237+
};
238+
239+
const isNotCurrent = (index: number) =>
240+
(index === 0 || index === 11) &&
241+
(props.type === 'year' || props.type === 'yearRange');
242+
243+
// 监听手指开始滑动事件
244+
const touchStart = (event: TouchEvent) => {
245+
emit('touchstart', event);
246+
};
247+
248+
// 监听手指开始滑动事件
249+
const touchMove = (event: TouchEvent) => {
250+
emit('touchmove', event);
251+
};
252+
253+
// 监听手指开始滑动事件
254+
const touchEnd = (event: TouchEvent) => {
255+
emit('touchend', event);
256+
};
257+
258+
watch(
259+
() => props.type,
260+
(val) => {
261+
disabledScrollDirec.value = props.disabledScroll;
262+
if (val === 'month') {
263+
disabledScrollDirec.value = true;
264+
yearMonthShow.value = [
265+
language.value.MONTH,
266+
language.value.MONTH,
267+
language.value.MONTH,
268+
];
269+
} else if (val === 'year') {
270+
yearMonthShow.value = getThreeYearArr();
271+
} else if (val === 'yearRange') {
272+
yearMonthShow.value = getThreeYearRangeArr();
273+
}
274+
}
275+
);
276+
},
277+
});

0 commit comments

Comments
 (0)