mirror of
https://github.com/youzan/vant.git
synced 2025-10-20 18:54:24 +00:00
feat(Calendar): lazy render
This commit is contained in:
@@ -1,14 +1,73 @@
|
||||
import { createNamespace } from '../../utils';
|
||||
import { t, bem } from '../utils';
|
||||
import { t, bem, compareDay, formatMonthTitle } from '../utils';
|
||||
import { getMonthEndDay } from '../../datetime-picker/utils';
|
||||
|
||||
const [createComponent] = createNamespace('calendar-month');
|
||||
|
||||
export default createComponent({
|
||||
props: {
|
||||
date: Date,
|
||||
days: Array,
|
||||
title: String,
|
||||
showMark: Boolean
|
||||
type: String,
|
||||
minDate: Date,
|
||||
maxDate: Date,
|
||||
showMark: Boolean,
|
||||
showTitle: Boolean,
|
||||
rowHeight: Number,
|
||||
currentValue: [Date, Array]
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
visible: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
title() {
|
||||
return formatMonthTitle(this.date);
|
||||
},
|
||||
|
||||
offset() {
|
||||
const day = this.date.getDay();
|
||||
return day > 0 ? day - 1 : 6;
|
||||
},
|
||||
|
||||
totalDay() {
|
||||
return getMonthEndDay(this.date.getFullYear(), this.date.getMonth() + 1);
|
||||
},
|
||||
|
||||
monthStyle() {
|
||||
if (!this.visible) {
|
||||
const padding =
|
||||
Math.ceil((this.totalDay + this.offset) / 7) * this.rowHeight;
|
||||
|
||||
return {
|
||||
paddingBottom: `${padding}px`
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
days() {
|
||||
if (!this.visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const days = [];
|
||||
const year = this.date.getFullYear();
|
||||
const month = this.date.getMonth();
|
||||
|
||||
for (let i = 1; i <= this.totalDay; i++) {
|
||||
const date = new Date(year, month, i);
|
||||
|
||||
days.push({
|
||||
day: i,
|
||||
date,
|
||||
type: this.getDayType(date)
|
||||
});
|
||||
}
|
||||
|
||||
return days;
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
@@ -16,6 +75,44 @@ export default createComponent({
|
||||
},
|
||||
|
||||
methods: {
|
||||
getDayType(day) {
|
||||
const { type, minDate, maxDate, currentValue } = this;
|
||||
|
||||
if (compareDay(day, minDate) < 0 || compareDay(day, maxDate) > 0) {
|
||||
return 'disabled';
|
||||
}
|
||||
|
||||
if (type === 'single') {
|
||||
return compareDay(day, currentValue) === 0 ? 'selected' : '';
|
||||
}
|
||||
|
||||
if (type === 'range') {
|
||||
const [startDay, endDay] = this.currentValue;
|
||||
|
||||
if (!startDay) {
|
||||
return;
|
||||
}
|
||||
|
||||
const compareToStart = compareDay(day, startDay);
|
||||
if (compareToStart === 0) {
|
||||
return 'start';
|
||||
}
|
||||
|
||||
if (!endDay) {
|
||||
return;
|
||||
}
|
||||
|
||||
const compareToEnd = compareDay(day, endDay);
|
||||
if (compareToEnd === 0) {
|
||||
return 'end';
|
||||
}
|
||||
|
||||
if (compareToStart > 0 && compareToEnd < 0) {
|
||||
return 'middle';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getLabel(item) {
|
||||
if (item.type === 'start') {
|
||||
return t('start');
|
||||
@@ -27,7 +124,7 @@ export default createComponent({
|
||||
},
|
||||
|
||||
genTitle() {
|
||||
if (this.title) {
|
||||
if (this.showTitle) {
|
||||
return <div class={bem('month-title')}>{this.title}</div>;
|
||||
}
|
||||
},
|
||||
@@ -38,9 +135,27 @@ export default createComponent({
|
||||
}
|
||||
},
|
||||
|
||||
genDay(item) {
|
||||
genDays() {
|
||||
if (this.visible) {
|
||||
return (
|
||||
<div class={bem('days')}>
|
||||
{this.genMark()}
|
||||
{this.days.map(this.genDay)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
genDay(item, index) {
|
||||
const { type } = item;
|
||||
|
||||
let style;
|
||||
if (index === 0) {
|
||||
style = {
|
||||
marginLeft: `${(100 * this.offset) / 7}%`
|
||||
};
|
||||
}
|
||||
|
||||
const onClick = () => {
|
||||
if (type !== 'disabled') {
|
||||
this.$emit('click', item);
|
||||
@@ -49,7 +164,7 @@ export default createComponent({
|
||||
|
||||
if (type === 'selected') {
|
||||
return (
|
||||
<div class={bem('day')} onClick={onClick}>
|
||||
<div style={style} class={bem('day')} onClick={onClick}>
|
||||
<div class={bem('selected-day')}>{item.day}</div>
|
||||
</div>
|
||||
);
|
||||
@@ -59,7 +174,7 @@ export default createComponent({
|
||||
const Label = label && <div class={bem('day-label')}>{label}</div>;
|
||||
|
||||
return (
|
||||
<div class={bem('day', [type])} onClick={onClick}>
|
||||
<div style={style} class={bem('day', [type])} onClick={onClick}>
|
||||
{item.day}
|
||||
{Label}
|
||||
</div>
|
||||
@@ -69,12 +184,9 @@ export default createComponent({
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class={bem('month')}>
|
||||
<div class={bem('month')} style={this.monthStyle}>
|
||||
{this.genTitle()}
|
||||
<div class={bem('days')}>
|
||||
{this.genMark()}
|
||||
{this.days.map(this.genDay)}
|
||||
</div>
|
||||
{this.genDays()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user