Skip to content

Commit

Permalink
fix: 🐛 修复Calendar部分文字运行时切换国际化未应用国际化文字的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
Moonofweisheng committed Apr 5, 2024
1 parent 8f11c8a commit 857c922
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
@scroll="monthScroll"
:scroll-top="scrollTop"
>
<view v-for="(item, index) in months(minDate, maxDate)" :key="index" :id="`month${index}`">
<view v-for="(item, index) in months" :key="index" :id="`month${index}`">
<month
:type="type"
:date="item.date"
Expand Down Expand Up @@ -60,7 +60,7 @@ export default {
</script>

<script lang="ts" setup>
import { computed, onBeforeMount, ref, watch } from 'vue'
import { computed, ref, watch, onMounted } from 'vue'
import { debounce, isArray, isEqual, isNumber, requestAnimationFrame } from '../../common/util'
import { compareMonth, formatMonthTitle, getMonthEndDay, getMonths, getTimeData, getWeekLabel } from '../utils'
import Month from '../month/month.vue'
Expand All @@ -71,13 +71,48 @@ import type { CalendarItem } from '../types'
const props = defineProps(monthPanelProps)
const { translate } = useTranslate('calendar-view')
const title = ref<string>('')
const scrollTop = ref<number>(0) // 滚动位置
const timeValue = ref<string[] | number[]>([])
const timeData = ref<Array<CalendarItem[]>>([])
const scrollIndex = ref<number>(0) // 当前显示的月份索引
const timeValue = ref<number[]>([]) // 当前选中的时分秒
const timeType = ref<MonthPanelTimeType>('') // 当前时间类型,是开始还是结束
const innerValue = ref<string | number | (number | null)[]>('') // 内部保存一个值,用于判断新老值,避免监听器触发
// 时间picker的列数据
const timeData = computed<Array<CalendarItem[]>>(() => {
let timeColumns: Array<CalendarItem[]> = []
if (props.type === 'datetime' && isNumber(props.value)) {
const date = new Date(props.value)
date.setHours(timeValue.value[0])
date.setMinutes(timeValue.value[1])
date.setSeconds(props.hideSecond ? 0 : timeValue.value[2])
const dateTime = date.getTime()
timeColumns = getTime(dateTime) || []
} else if (isArray(props.value) && props.type === 'datetimerange') {
const [start, end] = props.value!
const dataValue = timeType.value === 'start' ? start : end
const date = new Date(dataValue || '')
date.setHours(timeValue.value[0])
date.setMinutes(timeValue.value[1])
date.setSeconds(props.hideSecond ? 0 : timeValue.value[2])
const dateTime = date.getTime()
const finalValue = [start, end]
if (timeType.value === 'start') {
finalValue[0] = dateTime
} else {
finalValue[1] = dateTime
}
timeColumns = getTime(finalValue, timeType.value) || []
}
return timeColumns
})
// 标题
const title = computed(() => {
return formatMonthTitle(months.value[scrollIndex.value].date)
})
// 周标题
const weekLabel = computed(() => {
return (index: number) => {
return getWeekLabel(index - 1)
Expand All @@ -91,26 +126,23 @@ const scrollHeight = computed(() => {
})
// 月份日期和月份高度
const months = computed(() => {
return (minDate: number, maxDate: number): MonthInfo[] => {
let months = getMonths(minDate, maxDate).map((month) => {
const offset = (7 + new Date(month).getDay() - props.firstDayOfWeek) % 7
const totalDay = getMonthEndDay(new Date(month).getFullYear(), new Date(month).getMonth() + 1)
return {
height: (offset + totalDay > 35 ? 64 * 6 : 64 * 5) + 45,
date: month
}
})
return months
}
const months = computed<MonthInfo[]>(() => {
return getMonths(props.minDate, props.maxDate).map((month) => {
const offset = (7 + new Date(month).getDay() - props.firstDayOfWeek) % 7
const totalDay = getMonthEndDay(new Date(month).getFullYear(), new Date(month).getMonth() + 1)
return {
height: (offset + totalDay > 35 ? 64 * 6 : 64 * 5) + 45,
date: month
}
})
})
watch(
() => props.type,
(val) => {
if (
(val === 'datetime' && props.value) ||
(val === 'datetimerange' && typeof props.value === 'object' && props.value && props.value.length > 0 && props.value[0])
(val === 'datetimerange' && isArray(props.value) && props.value && props.value.length > 0 && props.value[0])
) {
setTime(props.value, 'start')
}
Expand All @@ -126,7 +158,7 @@ watch(
(val) => {
if (isEqual(val, innerValue.value)) return
if ((props.type === 'datetime' && val) || (props.type === 'datetimerange' && val && typeof val === 'object' && val.length > 0 && val[0])) {
if ((props.type === 'datetime' && val) || (props.type === 'datetimerange' && val && isArray(val) && val.length > 0 && val[0])) {
setTime(val, 'start')
}
},
Expand All @@ -136,7 +168,7 @@ watch(
}
)
onBeforeMount(() => {
onMounted(() => {
scrollIntoView()
})
Expand Down Expand Up @@ -164,14 +196,12 @@ function scrollIntoView() {
activeDate = Date.now()
}
const monthsInfo = months.value(props.minDate, props.maxDate)
let top: number = 0
for (let index = 0; index < monthsInfo.length; index++) {
if (compareMonth(monthsInfo[index].date, activeDate) === 0) {
for (let index = 0; index < months.value.length; index++) {
if (compareMonth(months.value[index].date, activeDate) === 0) {
break
}
top += monthsInfo[index] ? Number(monthsInfo[index].height) : 0
top += months.value[index] ? Number(months.value[index].height) : 0
}
scrollTop.value = 0
requestAnimationFrame(() => {
Expand Down Expand Up @@ -240,9 +270,8 @@ function setTime(value: number | (number | null)[], type?: MonthPanelTimeType) {
if (isArray(value) && value[0] && value[1] && type === 'start' && timeType.value === 'start') {
type = 'end'
}
timeData.value = getTime(value, type) || []
timeValue.value = getTimeValue(value, type || '')
timeType.value = type || ''
timeValue.value = getTimeValue(value, type || '')
}
function handleDateChange({ value, type }: { value: number | (number | null)[]; type?: MonthPanelTimeType }) {
if (!isEqual(value, props.value)) {
Expand All @@ -259,16 +288,14 @@ function handleTimeChange({ value }: { value: any[] }) {
if (!props.value) {
return
}
if (props.type === 'datetime' && typeof props.value === 'number') {
if (props.type === 'datetime' && isNumber(props.value)) {
const date = new Date(props.value)
date.setHours(value[0])
date.setMinutes(value[1])
date.setSeconds(props.hideSecond ? 0 : value[2])
const dateTime = date.getTime()
timeData.value = getTime(dateTime) || []
timeValue.value = value
handleChange(dateTime)
} else if (typeof props.value === 'object') {
} else if (isArray(props.value) && props.type === 'datetimerange') {
const [start, end] = props.value!
const dataValue = timeType.value === 'start' ? start : end
const date = new Date(dataValue || '')
Expand All @@ -285,9 +312,6 @@ function handleTimeChange({ value }: { value: any[] }) {
} else {
finalValue[1] = dateTime
}
timeData.value = getTime(finalValue, timeType.value) || []
timeValue.value = value
innerValue.value = finalValue // 内部保存一个值,用于判断新老值,避免监听器触发
handleChange(finalValue)
}
Expand All @@ -300,24 +324,23 @@ function handlePickEnd() {
}
const monthScroll = (event: { detail: { scrollTop: number } }) => {
const monthsInfo = months.value(props.minDate, props.maxDate)
if (monthsInfo.length <= 1) {
if (months.value.length <= 1) {
return
}
const scrollTop = Math.max(0, event.detail.scrollTop)
doSetSubtitle(scrollTop, monthsInfo)
doSetSubtitle(scrollTop)
}
/**
* 设置小标题
* scrollTop 滚动条位置
*/
function doSetSubtitle(scrollTop: number, monthsInfo: MonthInfo[]) {
function doSetSubtitle(scrollTop: number) {
let height: number = 0 // 月份高度和
for (let index = 0; index < monthsInfo.length; index++) {
height = height + monthsInfo[index].height
for (let index = 0; index < months.value.length; index++) {
height = height + months.value[index].height
if (scrollTop < height + 45) {
title.value = formatMonthTitle(monthsInfo[index].date)
scrollIndex.value = index
return
}
}
Expand Down
23 changes: 13 additions & 10 deletions src/uni_modules/wot-design-uni/components/wd-calendar-view/utils.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { computed } from 'vue'
import { dayjs } from '../common/dayjs'
import { isArray, isFunction, padZero } from '../common/util'
import { useTranslate } from '../composables/useTranslate'
import type { CalendarDayType, CalendarItem, CalendarTimeFilter, CalendarType } from './types'
const { translate } = useTranslate('calendar-view')

const weeks: string[] = [
translate('weeks.sun'),
translate('weeks.mon'),
translate('weeks.tue'),
translate('weeks.wed'),
translate('weeks.thu'),
translate('weeks.fri'),
translate('weeks.sat')
]
const weeks = computed(() => {
return [
translate('weeks.sun'),
translate('weeks.mon'),
translate('weeks.tue'),
translate('weeks.wed'),
translate('weeks.thu'),
translate('weeks.fri'),
translate('weeks.sat')
]
})

/**
* 比较两个时间的日期是否相等
Expand Down Expand Up @@ -110,7 +113,7 @@ export function getWeekLabel(index: number) {
index = index % 7
}

return weeks[index]
return weeks.value[index]
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<view class="wd-year-panel">
<view v-if="showPanelTitle" class="wd-year-panel__title">{{ title }}</view>
<scroll-view class="wd-year-panel__container" :style="`height: ${scrollHeight}px`" scroll-y @scroll="yearScroll" :scroll-top="scrollTop">
<view v-for="(item, index) in years(minDate, maxDate)" :key="index" :id="`year${index}`">
<view v-for="(item, index) in years" :key="index" :id="`year${index}`">
<year
:type="type"
:date="item.date"
Expand Down Expand Up @@ -31,38 +31,41 @@ export default {
</script>

<script lang="ts" setup>
import { computed, ref, onBeforeMount } from 'vue'
import { computed, ref, onMounted } from 'vue'
import { compareYear, formatYearTitle, getYears } from '../utils'
import { isArray, isNumber, requestAnimationFrame } from '../../common/util'
import Year from '../year/year.vue'
import { yearPanelProps, type YearInfo, type YearPanelExpose } from './types'
const props = defineProps(yearPanelProps)
const title = ref<string>('')
const scrollTop = ref<number>(0) // 滚动位置
const scrollIndex = ref<number>(0) // 当前显示的年份索引
// 滚动区域的高度
const scrollHeight = computed(() => {
const scrollHeight: number = (props.panelHeight || 378) + (props.showPanelTitle ? 26 : 16)
return scrollHeight
})
const years = computed(() => {
return (minDate: number, maxDate: number): YearInfo[] => {
let years = getYears(minDate, maxDate).map((year) => {
return {
date: year,
height: 237
}
})
return years
}
// 年份信息
const years = computed<YearInfo[]>(() => {
return getYears(props.minDate, props.maxDate).map((year) => {
return {
date: year,
height: 237
}
})
})
// 标题
const title = computed(() => {
return formatYearTitle(years.value[scrollIndex.value].date)
})
const emit = defineEmits(['change'])
onBeforeMount(() => {
onMounted(() => {
scrollIntoView()
})
Expand All @@ -79,14 +82,12 @@ function scrollIntoView() {
activeDate = Date.now()
}
const yearsInfo = years.value(props.minDate, props.maxDate)
let top: number = 0
for (let index = 0; index < yearsInfo.length; index++) {
if (compareYear(yearsInfo[index].date, activeDate) === 0) {
for (let index = 0; index < years.value.length; index++) {
if (compareYear(years.value[index].date, activeDate) === 0) {
break
}
top += yearsInfo[index] ? Number(yearsInfo[index].height) : 0
top += years.value[index] ? Number(years.value[index].height) : 0
}
scrollTop.value = 0
requestAnimationFrame(() => {
Expand All @@ -96,24 +97,23 @@ function scrollIntoView() {
}
const yearScroll = (e: Event) => {
const yearsInfo = years.value(props.minDate, props.maxDate)
if (yearsInfo.length <= 1) {
if (years.value.length <= 1) {
return
}
const scrollTop = Math.max(0, (e.target as Element).scrollTop)
doSetSubtitle(scrollTop, yearsInfo)
doSetSubtitle(scrollTop)
}
/**
* 设置小标题
* scrollTop 滚动条位置
*/
function doSetSubtitle(scrollTop: number, yearsInfo: YearInfo[]) {
function doSetSubtitle(scrollTop: number) {
let height: number = 0 // 月份高度和
for (let index = 0; index < yearsInfo.length; index++) {
height = height + yearsInfo[index].height
for (let index = 0; index < years.value.length; index++) {
height = height + years.value[index].height
if (scrollTop < height + 45) {
title.value = formatYearTitle(yearsInfo[index].date)
scrollIndex.value = index
return
}
}
Expand Down
Loading

0 comments on commit 857c922

Please sign in to comment.