refactor(components): [calendar] (#10163)

* refactor(components): [calendar]

* Eliminate long function by extracting code as function calls.

* chore: move t out of use-calendar logic
This commit is contained in:
Jeremy 2022-10-22 11:39:18 +08:00 committed by GitHub
parent 6d624f1a76
commit d3a32cdd0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 59 deletions

View File

@ -52,8 +52,9 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'
import { ElButton, ElButtonGroup } from '@element-plus/components/button' import { ElButton, ElButtonGroup } from '@element-plus/components/button'
import { useNamespace } from '@element-plus/hooks' import { useLocale, useNamespace } from '@element-plus/hooks'
import DateTable from './date-table.vue' import DateTable from './date-table.vue'
import { useCalendar } from './use-calendar' import { useCalendar } from './use-calendar'
@ -75,11 +76,16 @@ const {
pickDay, pickDay,
realSelectedDay, realSelectedDay,
selectDate, selectDate,
t,
i18nDate,
validatedRange, validatedRange,
} = useCalendar(props, emit, COMPONENT_NAME) } = useCalendar(props, emit, COMPONENT_NAME)
const { t } = useLocale()
const i18nDate = computed(() => {
const pickedMonth = `el.datepicker.month${date.value.format('M')}`
return `${date.value.year()} ${t('el.datepicker.year')} ${t(pickedMonth)}`
})
defineExpose({ defineExpose({
/** @description currently selected date */ /** @description currently selected date */
selectedDay: realSelectedDay, selectedDay: realSelectedDay,

View File

@ -8,13 +8,56 @@ import type { ComputedRef, SetupContext } from 'vue'
import type { Dayjs } from 'dayjs' import type { Dayjs } from 'dayjs'
import type { CalendarDateType, CalendarEmits, CalendarProps } from './calendar' import type { CalendarDateType, CalendarEmits, CalendarProps } from './calendar'
const adjacentMonth = (start: Dayjs, end: Dayjs): [Dayjs, Dayjs][] => {
const firstMonthLastDay = start.endOf('month')
const lastMonthFirstDay = end.startOf('month')
// Whether the last day of the first month and the first day of the last month is in the same week
const isSameWeek = firstMonthLastDay.isSame(lastMonthFirstDay, 'week')
const lastMonthStartDay = isSameWeek
? lastMonthFirstDay.add(1, 'week')
: lastMonthFirstDay
return [
[start, firstMonthLastDay],
[lastMonthStartDay.startOf('week'), end],
]
}
const threeConsecutiveMonth = (start: Dayjs, end: Dayjs): [Dayjs, Dayjs][] => {
const firstMonthLastDay = start.endOf('month')
const secondMonthFirstDay = start.add(1, 'month').startOf('month')
// Whether the last day of the first month and the second month is in the same week
const secondMonthStartDay = firstMonthLastDay.isSame(
secondMonthFirstDay,
'week'
)
? secondMonthFirstDay.add(1, 'week')
: secondMonthFirstDay
const secondMonthLastDay = secondMonthStartDay.endOf('month')
const lastMonthFirstDay = end.startOf('month')
// Whether the last day of the second month and the last day of the last month is in the same week
const lastMonthStartDay = secondMonthLastDay.isSame(lastMonthFirstDay, 'week')
? lastMonthFirstDay.add(1, 'week')
: lastMonthFirstDay
return [
[start, firstMonthLastDay],
[secondMonthStartDay.startOf('week'), secondMonthLastDay],
[lastMonthStartDay.startOf('week'), end],
]
}
export const useCalendar = ( export const useCalendar = (
props: CalendarProps, props: CalendarProps,
emit: SetupContext<CalendarEmits>['emit'], emit: SetupContext<CalendarEmits>['emit'],
componentName: string componentName: string
) => { ) => {
const solts = useSlots() const slots = useSlots()
const { t, lang } = useLocale() const { lang } = useLocale()
const selectedDay = ref<Dayjs>() const selectedDay = ref<Dayjs>()
const now = dayjs().locale(lang.value) const now = dayjs().locale(lang.value)
@ -61,12 +104,10 @@ export const useCalendar = (
const date: ComputedRef<Dayjs> = computed(() => { const date: ComputedRef<Dayjs> = computed(() => {
if (!props.modelValue) { if (!props.modelValue) {
if (realSelectedDay.value) { return (
return realSelectedDay.value realSelectedDay.value ||
} else if (validatedRange.value.length) { (validatedRange.value.length ? validatedRange.value[0][0] : now)
return validatedRange.value[0][0] )
}
return now
} else { } else {
return dayjs(props.modelValue).locale(lang.value) return dayjs(props.modelValue).locale(lang.value)
} }
@ -76,11 +117,6 @@ export const useCalendar = (
const prevYearDayjs = computed(() => date.value.subtract(1, 'year').date(1)) const prevYearDayjs = computed(() => date.value.subtract(1, 'year').date(1))
const nextYearDayjs = computed(() => date.value.add(1, 'year').date(1)) const nextYearDayjs = computed(() => date.value.add(1, 'year').date(1))
const i18nDate = computed(() => {
const pickedMonth = `el.datepicker.month${date.value.format('M')}`
return `${date.value.year()} ${t('el.datepicker.year')} ${t(pickedMonth)}`
})
// https://github.com/element-plus/element-plus/issues/3155 // https://github.com/element-plus/element-plus/issues/3155
// Calculate the validate date range according to the start and end dates // Calculate the validate date range according to the start and end dates
const calculateValidatedDateRange = ( const calculateValidatedDateRange = (
@ -98,52 +134,14 @@ export const useCalendar = (
} }
// Two adjacent months // Two adjacent months
else if (firstMonth + 1 === lastMonth) { else if (firstMonth + 1 === lastMonth) {
const firstMonthLastDay = firstDay.endOf('month') return adjacentMonth(firstDay, lastDay)
const lastMonthFirstDay = lastDay.startOf('month')
// Whether the last day of the first month and the first day of the last month is in the same week
const isSameWeek = firstMonthLastDay.isSame(lastMonthFirstDay, 'week')
const lastMonthStartDay = isSameWeek
? lastMonthFirstDay.add(1, 'week')
: lastMonthFirstDay
return [
[firstDay, firstMonthLastDay],
[lastMonthStartDay.startOf('week'), lastDay],
]
} }
// Three consecutive months (compatible: 2021-01-30 to 2021-02-28) // Three consecutive months (compatible: 2021-01-30 to 2021-02-28)
else if ( else if (
firstMonth + 2 === lastMonth || firstMonth + 2 === lastMonth ||
(firstMonth + 1) % 11 === lastMonth (firstMonth + 1) % 11 === lastMonth
) { ) {
const firstMonthLastDay = firstDay.endOf('month') return threeConsecutiveMonth(firstDay, lastDay)
const secondMonthFirstDay = firstDay.add(1, 'month').startOf('month')
// Whether the last day of the first month and the second month is in the same week
const secondMonthStartDay = firstMonthLastDay.isSame(
secondMonthFirstDay,
'week'
)
? secondMonthFirstDay.add(1, 'week')
: secondMonthFirstDay
const secondMonthLastDay = secondMonthStartDay.endOf('month')
const lastMonthFirstDay = lastDay.startOf('month')
// Whether the last day of the second month and the last day of the last month is in the same week
const lastMonthStartDay = secondMonthLastDay.isSame(
lastMonthFirstDay,
'week'
)
? lastMonthFirstDay.add(1, 'week')
: lastMonthFirstDay
return [
[firstDay, firstMonthLastDay],
[secondMonthStartDay.startOf('week'), secondMonthLastDay],
[lastMonthStartDay.startOf('week'), lastDay],
]
} }
// Other cases // Other cases
else { else {
@ -184,7 +182,7 @@ export const useCalendar = (
ref: 'https://element-plus.org/en-US/component/calendar.html#slots', ref: 'https://element-plus.org/en-US/component/calendar.html#slots',
type: 'Slot', type: 'Slot',
}, },
computed(() => !!solts.dateCell) computed(() => !!slots.dateCell)
) )
return { return {
@ -194,7 +192,5 @@ export const useCalendar = (
pickDay, pickDay,
selectDate, selectDate,
validatedRange, validatedRange,
t,
i18nDate,
} }
} }