Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

优化大跨度时间段的性能表现 #5647

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 20 additions & 19 deletions packages/calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,25 +267,26 @@ Page({

### Props

| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| type | 选择类型:<br>`single`表示选择单个日期,<br>`multiple`表示选择多个日期,<br>`range`表示选择日期区间 | _string_ | `single` |
| title | 日历标题 | _string_ | `日期选择` |
| color | 主题色,对底部按钮和选中日期生效 | _string_ | `#ee0a24` |
| min-date | 可选择的最小日期 | _timestamp_ | 当前日期 |
| max-date | 可选择的最大日期 | _timestamp_ | 当前日期的六个月后 |
| default-date `v1.10.21` | 默认选中的日期,`type`为`multiple`或`range`时为数组,传入 `null` 表示默认不选择| _timestamp \| timestamp[] \| null_ | 今天 |
| row-height | 日期行高 | _number \| string_ | `64` |
| formatter | 日期格式化函数 | _(day: Day) => Day_ | - |
| poppable | 是否以弹层的形式展示日历 | _boolean_ | `true` |
| show-mark | 是否显示月份背景水印 | _boolean_ | `true` |
| show-title | 是否展示日历标题 | _boolean_ | `true` |
| show-subtitle | 是否展示日历副标题(年月) | _boolean_ | `true` |
| show-confirm | 是否展示确认按钮 | _boolean_ | `true` |
| confirm-text | 确认按钮的文字 | _string_ | `确定` |
| confirm-disabled-text | 确认按钮处于禁用状态时的文字 | _string_ | `确定` |
| first-day-of-week | 设置周起始日 | _0~6_ | `0` |
| readonly `v1.9.1` | 是否为只读状态,只读状态下不能选择日期 | _boolean_ | `false` |
| 参数 | 说明 | 类型 | 默认值 |
|-------------------------|----------------------------------------------------------------------|---------------------|---------------|
| type | 选择类型:<br>`single`表示选择单个日期,<br>`multiple`表示选择多个日期,<br>`range`表示选择日期区间 | _string_ | `single` |
| title | 日历标题 | _string_ | `日期选择` |
| color | 主题色,对底部按钮和选中日期生效 | _string_ | `#ee0a24` |
| min-date | 可选择的最小日期 | _timestamp_ | 当前日期 |
| max-date | 可选择的最大日期 | _timestamp_ | 当前日期的六个月后 |
| default-date `v1.10.21` | 默认选中的日期,`type`为`multiple`或`range`时为数组,传入 `null` 表示默认不选择 | _timestamp \ | timestamp[] \ | null_ | 今天 |
| row-height | 日期行高 | _number \ | string_ | `64` |
| formatter | 日期格式化函数 | _(day: Day) => Day_ | - |
| poppable | 是否以弹层的形式展示日历 | _boolean_ | `true` |
| show-mark | 是否显示月份背景水印 | _boolean_ | `true` |
| show-title | 是否展示日历标题 | _boolean_ | `true` |
| show-subtitle | 是否展示日历副标题(年月) | _boolean_ | `true` |
| show-confirm | 是否展示确认按钮 | _boolean_ | `true` |
| confirm-text | 确认按钮的文字 | _string_ | `确定` |
| confirm-disabled-text | 确认按钮处于禁用状态时的文字 | _string_ | `确定` |
| first-day-of-week | 设置周起始日 | _0~6_ | `0` |
| readonly `v1.9.1` | 是否为只读状态,只读状态下不能选择日期 | _boolean_ | `false` |
| maxSimDays | 最大同时显示天数。超出限制外只会同时显示当前滚动条所在月份前后三个月的日期数据 | _number_ | `300` |

### Poppable Props

Expand Down
2 changes: 2 additions & 0 deletions packages/calendar/calendar.wxml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
<scroll-view
class="van-calendar__body"
scroll-y
bindscroll="scrolling"
scroll-into-view="{{ scrollIntoView }}"
>
<month
wx:for="{{ computed.getMonths(minDate, maxDate) }}"
wx:key="index"
id="month{{ index }}"
class="month"
visible="{{!monthVisibleControl || monthHideMap[index]}}"
data-date="{{ item }}"
date="{{ item }}"
type="{{ type }}"
Expand Down
7 changes: 6 additions & 1 deletion packages/calendar/components/month/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ VantComponent({
type: null,
observer: 'setDays',
},
visible: {
type: Boolean,
value: true,
observer: 'setDays',
},
showMark: Boolean,
rowHeight: null,
formatter: {
Expand All @@ -52,7 +57,7 @@ VantComponent({
},

data: {
visible: true,
// visible: true,
days: [] as Day[],
},

Expand Down
2 changes: 1 addition & 1 deletion packages/calendar/demo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ VantComponent({
showConfirm: false,
showCalendar: false,
tiledMinDate: new Date(2012, 0, 10).getTime(),
tiledMaxDate: new Date(2012, 2, 20).getTime(),
tiledMaxDate: new Date(2030, 2, 20).getTime(),
confirmText: '确定',
confirmDisabledText: '确定',
firstDayOfWeek: 0,
Expand Down
1 change: 1 addition & 0 deletions packages/calendar/demo/index.wxml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
title="日历"
poppable="{{ false }}"
show-confirm="{{ false }}"
type="range"
min-date="{{ tiledMinDate }}"
max-date="{{ tiledMaxDate }}"
first-day-of-week="{{ firstDayOfWeek }}"
Expand Down
90 changes: 79 additions & 11 deletions packages/calendar/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { VantComponent } from '../common/component';
import {
ROW_HEIGHT,
getPrevDay,
getNextDay,
getToday,
compareDay,
copyDates,
calcDateNum,
formatMonthTitle,
compareMonth,
getMonths,
getDayByOffset,
ROW_HEIGHT,
getPrevDay,
getNextDay,
getToday,
compareDay,
copyDates,
calcDateNum,
formatMonthTitle,
compareMonth,
getMonths,
getDayByOffset,
} from './utils';
import { Day } from './components/month/index';

Expand Down Expand Up @@ -136,12 +136,19 @@ VantComponent({
value: 0,
},
readonly: Boolean,
maxSimDays: {
type: Number,
value: 300
}
},

data: {
subtitle: '',
currentDate: null as any,
scrollIntoView: '',
monthData:[],
monthVisibleControl: false,
monthHideMap: {}
},

watch: {
Expand All @@ -167,12 +174,73 @@ VantComponent({
},

methods: {
scrolling (e) {
const me = this;
if (me.data.timer) {
clearTimeout(me.data.timer);
}
me.data.timer = setTimeout(()=>{
const {minDate, maxDate} = me.data;
let monthData: number[] = me.data.monthData;
if (!monthData?.length) {
monthData = getMonths(minDate, maxDate)
}
const {scrollTop, scrollHeight} = e.detail;
// 每一行的高度。
const cHeight = scrollHeight / (monthData.length);
// 当前所在月
const curMonth = Math.floor(scrollTop / cHeight);
const monthHideMap: {[key: string]: boolean} = {};
for (let i = Math.max(0, curMonth - 1); i < Math.min(monthData.length, curMonth+3); i++) {
monthHideMap[i] = true;
}
me.setData({
// @ts-ignore
monthData,
scrollTop,
scrollHeight,
cHeight,
monthHideMap,
})
clearTimeout(this.data.timer);
}, 200)
},

reset() {
this.setData({ currentDate: this.getInitialDate(this.data.defaultDate) });
this.scrollIntoView();
},

initRect() {
// 新增 当minDate MaxDate区间大于 `maxSimDays` 天时,日历面板控制总节点数量,只显示当前选中前后三个月的月份日期。
const {minDate, maxDate, maxSimDays, cHeight, scrollTop, scrollHeight} = this.data;
if (minDate && maxDate && Math.abs(maxDate-minDate)>maxSimDays*24*60*60*1000) {
let monthData: number[] = this.data.monthData;
const monthHideMap: {[key: string]: boolean} = {};
if (!monthData?.length) {
monthData = getMonths(minDate, maxDate)
}
let minLoop = 0,maxLoop = 4;
if (scrollTop && cHeight && scrollHeight) {
let curMonth = Math.floor(scrollTop / cHeight);
minLoop = Math.max(0, curMonth-1);
maxLoop = Math.min(monthData.length, curMonth+3);
}
for (let i = minLoop; i < maxLoop; i++) {
monthHideMap[i] = true;
}

this.setData({
// @ts-ignore
monthData: monthData,
monthHideMap,
monthVisibleControl: true,
})
}else {
this.setData({
monthVisibleControl: false,
})
}
if (this.contentObserver != null) {
this.contentObserver.disconnect();
}
Expand Down