mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(Calendar): support select date range
This commit is contained in:
parent
c447152be9
commit
0db1a03996
@ -1,7 +1,7 @@
|
|||||||
import { createNamespace } from '../utils';
|
import { createNamespace } from '../utils';
|
||||||
import { t, formatMonthTitle } from './utils';
|
import { t, bem, formatMonthTitle } from './utils';
|
||||||
|
|
||||||
const [createComponent, bem] = createNamespace('calendar-header');
|
const [createComponent] = createNamespace('calendar-header');
|
||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
props: {
|
props: {
|
||||||
@ -11,14 +11,16 @@ export default createComponent({
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
genTitle() {
|
genTitle() {
|
||||||
if (this.title) {
|
const title = this.slots('title') || this.title || t('title');
|
||||||
return <div class={bem('title')}>{this.title}</div>;
|
|
||||||
|
if (title) {
|
||||||
|
return <div class={bem('header-title')}>{title}</div>;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
genMonth() {
|
genMonth() {
|
||||||
return (
|
return (
|
||||||
<div class={bem('month')}>
|
<div class={bem('month-title')}>
|
||||||
{formatMonthTitle(this.currentMonth)}
|
{formatMonthTitle(this.currentMonth)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -39,7 +41,7 @@ export default createComponent({
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div class={bem()}>
|
<div class={bem('header')}>
|
||||||
{this.genTitle()}
|
{this.genTitle()}
|
||||||
{this.genMonth()}
|
{this.genMonth()}
|
||||||
{this.genWeekDays()}
|
{this.genWeekDays()}
|
||||||
|
74
src/calendar/Month.js
Normal file
74
src/calendar/Month.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { createNamespace } from '../utils';
|
||||||
|
import { t, bem } from './utils';
|
||||||
|
|
||||||
|
const [createComponent] = createNamespace('calendar-month');
|
||||||
|
|
||||||
|
export default createComponent({
|
||||||
|
props: {
|
||||||
|
date: Date,
|
||||||
|
days: Array,
|
||||||
|
title: String
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.height = this.$el.getBoundingClientRect().height;
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getLabel(item) {
|
||||||
|
if (item.type === 'start') {
|
||||||
|
return t('start');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.type === 'end') {
|
||||||
|
return t('end');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
genTitle() {
|
||||||
|
if (this.title) {
|
||||||
|
return <div class={bem('month-title')}>{this.title}</div>;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
genDay(item) {
|
||||||
|
const { type } = item;
|
||||||
|
|
||||||
|
const onClick = () => {
|
||||||
|
if (type !== 'disabled') {
|
||||||
|
this.$emit('click', item);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (type === 'selected') {
|
||||||
|
return (
|
||||||
|
<div class={bem('day')} onClick={onClick}>
|
||||||
|
<div class={bem('selected-day')}>{item.day}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const label = this.getLabel(item);
|
||||||
|
const Label = label && <div class={bem('day-label')}>{label}</div>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={bem('day', [type])} onClick={onClick}>
|
||||||
|
{item.day}
|
||||||
|
{Label}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div class={bem('month')}>
|
||||||
|
{this.genTitle()}
|
||||||
|
<div class={bem('days')}>
|
||||||
|
<div class={bem('month-mark')}>{this.date.getMonth() + 1}</div>
|
||||||
|
{this.days.map(this.genDay)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
@ -1,5 +1,9 @@
|
|||||||
# Calendar 日历
|
# Calendar 日历
|
||||||
|
|
||||||
|
### 介绍
|
||||||
|
|
||||||
|
日历组件可以用于选择日期或日期区间,通常与 [弹出层](#/zh-CN/popup) 组件配合使用
|
||||||
|
|
||||||
### 引入
|
### 引入
|
||||||
|
|
||||||
``` javascript
|
``` javascript
|
||||||
@ -11,7 +15,7 @@ Vue.use(Calendar);
|
|||||||
|
|
||||||
## 代码演示
|
## 代码演示
|
||||||
|
|
||||||
### 基础用法
|
### 选择单个日期
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<van-calendar />
|
<van-calendar />
|
||||||
@ -26,8 +30,10 @@ Vue.use(Calendar);
|
|||||||
| v-model | 选中的日期 | `Date` | - | - |
|
| v-model | 选中的日期 | `Date` | - | - |
|
||||||
| type | 选择类型,`single`为选择单日,`range`为选择日期区间 | `string` | `single` | - |
|
| type | 选择类型,`single`为选择单日,`range`为选择日期区间 | `string` | `single` | - |
|
||||||
| title | 日历标题 | `string` | - | - |
|
| title | 日历标题 | `string` | - | - |
|
||||||
| min-date | 最小日期 | `Date` | 当前时间 | - |
|
| min-date | 最小日期 | `Date` | 当前日期 | - |
|
||||||
| max-date | 最大日期 | `Date` | 当前时间的六个月后 | - |
|
| max-date | 最大日期 | `Date` | 当前日期的六个月后 | - |
|
||||||
|
| confirm-text | 选择日期区间时,确认按钮的文字 | `string` | `确定` | - |
|
||||||
|
| confirm-disabled-text | 选择日期区间时,确认按钮处于禁用状态时的文字 | `string` | `确定` | - |
|
||||||
|
|
||||||
### Events
|
### Events
|
||||||
|
|
||||||
@ -39,6 +45,7 @@ Vue.use(Calendar);
|
|||||||
|
|
||||||
| 名称 | 说明 |
|
| 名称 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
|
| title | 自定义标题 |
|
||||||
|
|
||||||
### 方法
|
### 方法
|
||||||
|
|
||||||
|
@ -2,20 +2,46 @@
|
|||||||
<demo-section>
|
<demo-section>
|
||||||
<demo-block :title="$t('basicUsage')">
|
<demo-block :title="$t('basicUsage')">
|
||||||
<van-cell
|
<van-cell
|
||||||
:title="$t('selectDate')"
|
|
||||||
:value="formatDate(date.selectDate)"
|
|
||||||
is-link
|
is-link
|
||||||
@click="toggle('selectDate', true)"
|
:title="$t('selectSingleDate')"
|
||||||
|
:value="formatDate(date.selectSingleDate)"
|
||||||
|
@click="toggle('selectSingleDate', true)"
|
||||||
/>
|
/>
|
||||||
</demo-block>
|
|
||||||
|
|
||||||
<van-popup v-model="show.selectDate" round closeable position="bottom">
|
<van-popup
|
||||||
<van-calendar
|
v-model="show.selectSingleDate"
|
||||||
v-model="date.selectDate"
|
round
|
||||||
:title="$t('title')"
|
closeable
|
||||||
@select="show.selectDate = false"
|
position="bottom"
|
||||||
|
style="height: 80vh;"
|
||||||
|
>
|
||||||
|
<van-calendar
|
||||||
|
v-model="date.selectSingleDate"
|
||||||
|
@select="show.selectSingleDate = false"
|
||||||
|
/>
|
||||||
|
</van-popup>
|
||||||
|
|
||||||
|
<van-cell
|
||||||
|
is-link
|
||||||
|
:title="$t('selectDateRange')"
|
||||||
|
:value="formatDateRange(date.selectDateRange)"
|
||||||
|
@click="toggle('selectDateRange', true)"
|
||||||
/>
|
/>
|
||||||
</van-popup>
|
|
||||||
|
<van-popup
|
||||||
|
v-model="show.selectDateRange"
|
||||||
|
round
|
||||||
|
closeable
|
||||||
|
position="bottom"
|
||||||
|
style="height: 80vh;"
|
||||||
|
>
|
||||||
|
<van-calendar
|
||||||
|
v-model="date.selectDateRange"
|
||||||
|
type="range"
|
||||||
|
@select="show.selectDateRange = false"
|
||||||
|
/>
|
||||||
|
</van-popup>
|
||||||
|
</demo-block>
|
||||||
</demo-section>
|
</demo-section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -23,22 +49,24 @@
|
|||||||
export default {
|
export default {
|
||||||
i18n: {
|
i18n: {
|
||||||
'zh-CN': {
|
'zh-CN': {
|
||||||
title: '日期选择',
|
selectSingleDate: '选择单个日期',
|
||||||
selectDate: '选择日期'
|
selectDateRange: '选择日期区间'
|
||||||
},
|
},
|
||||||
'en-US': {
|
'en-US': {
|
||||||
title: 'Select Date',
|
selectSingleDate: 'Select Single Date',
|
||||||
selectDate: 'Select Date'
|
selectDateRange: 'Select Date Range'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
date: {
|
date: {
|
||||||
selectDate: null
|
selectSingleDate: null,
|
||||||
|
selectDateRange: []
|
||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
selectDate: false
|
selectSingleDate: false,
|
||||||
|
selectDateRange: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -52,6 +80,14 @@ export default {
|
|||||||
if (date) {
|
if (date) {
|
||||||
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
|
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
formatDateRange(dateRange) {
|
||||||
|
if (dateRange.length) {
|
||||||
|
return `${this.formatDate(dateRange[0])} - ${this.formatDate(
|
||||||
|
dateRange[1]
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,24 @@
|
|||||||
import { isDate } from '../utils/validate/date';
|
import { isDate } from '../utils/validate/date';
|
||||||
import { getScrollTop } from '../utils/dom/scroll';
|
import { getScrollTop } from '../utils/dom/scroll';
|
||||||
import { createComponent, bem, compareMonth, formatMonthTitle } from './utils';
|
import {
|
||||||
|
t,
|
||||||
|
bem,
|
||||||
|
getNextDay,
|
||||||
|
compareDay,
|
||||||
|
compareMonth,
|
||||||
|
createComponent,
|
||||||
|
formatMonthTitle
|
||||||
|
} from './utils';
|
||||||
|
import Month from './Month';
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
|
import Button from '../button';
|
||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
props: {
|
props: {
|
||||||
value: Date,
|
|
||||||
title: String,
|
title: String,
|
||||||
|
value: [Date, Array],
|
||||||
|
confirmText: String,
|
||||||
|
confirmDisabledText: String,
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'single'
|
default: 'single'
|
||||||
@ -28,7 +40,8 @@ export default createComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentMonth: this.minDate
|
currentMonth: this.minDate,
|
||||||
|
currentValue: this.getDefaultValue()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -54,42 +67,64 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
watch: {
|
||||||
this.initRects();
|
value(val) {
|
||||||
|
this.currentValue = val;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
initRects() {
|
getDefaultValue() {
|
||||||
this.monthsHeight = this.$refs.month.map(
|
const { type, value, minDate } = this;
|
||||||
month => month.getBoundingClientRect().height
|
|
||||||
);
|
if (type === 'single') {
|
||||||
|
return value || minDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'range') {
|
||||||
|
const range = value || [];
|
||||||
|
return [range[0] || minDate, range[1] || getNextDay(minDate)];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
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') {
|
||||||
|
if (!currentValue[0]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const compareWithStart = compareDay(day, currentValue[0]);
|
||||||
|
if (compareWithStart === 0) {
|
||||||
|
return 'start';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentValue[1]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const compareWithEnd = compareDay(day, currentValue[1]);
|
||||||
|
if (compareWithEnd === 0) {
|
||||||
|
return 'end';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compareWithStart > 0 && compareWithEnd < 0) {
|
||||||
|
return 'middle';
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getDays(date) {
|
getDays(date) {
|
||||||
const days = [];
|
const days = [];
|
||||||
const { minDate, maxDate } = this;
|
|
||||||
const checkMinDate = compareMonth(date, minDate) === 0;
|
|
||||||
const checkMaxDate = compareMonth(date, maxDate) === 0;
|
|
||||||
const checkSelected =
|
|
||||||
this.value &&
|
|
||||||
this.type === 'single' &&
|
|
||||||
compareMonth(date, this.value) === 0;
|
|
||||||
|
|
||||||
const isDisabled = date => {
|
|
||||||
if (checkMaxDate && date.getDate() > maxDate.getDate()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkMinDate && date.getDate() < minDate.getDate()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const isSelected = date =>
|
|
||||||
checkSelected && date.getDate() === this.value.getDate();
|
|
||||||
|
|
||||||
const placeholderCount = date.getDay() === 0 ? 6 : date.getDay() - 1;
|
const placeholderCount = date.getDay() === 0 ? 6 : date.getDay() - 1;
|
||||||
|
|
||||||
for (let i = 1; i <= placeholderCount; i++) {
|
for (let i = 1; i <= placeholderCount; i++) {
|
||||||
@ -102,8 +137,7 @@ export default createComponent({
|
|||||||
days.push({
|
days.push({
|
||||||
day: cursor.getDate(),
|
day: cursor.getDate(),
|
||||||
date: new Date(cursor),
|
date: new Date(cursor),
|
||||||
disabled: isDisabled(cursor),
|
type: this.getDayType(cursor)
|
||||||
selected: isSelected(cursor)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
cursor.setDate(cursor.getDate() + 1);
|
cursor.setDate(cursor.getDate() + 1);
|
||||||
@ -113,46 +147,21 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
genMonth(month, index) {
|
genMonth(month, index) {
|
||||||
const Title = index !== 0 && (
|
|
||||||
<div class={bem('month-title')}>{month.title}</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const Days = month.days.map(item => {
|
|
||||||
const onClick = () => {
|
|
||||||
this.onClickDay(item);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (item.selected) {
|
|
||||||
return (
|
|
||||||
<div class={bem('day')} onClick={onClick}>
|
|
||||||
<div class={bem('selected-day')}>{item.day}</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
class={bem('day', { disabled: item.disabled })}
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
{item.day}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={bem('month')} ref="month" refInFor>
|
<Month
|
||||||
{Title}
|
ref="month"
|
||||||
<div class={bem('days')}>
|
refInFor
|
||||||
<div class={bem('month-mark')}>{month.date.getMonth() + 1}</div>
|
days={month.days}
|
||||||
{Days}
|
date={month.date}
|
||||||
</div>
|
title={index !== 0 ? month.title : ''}
|
||||||
</div>
|
onClick={this.onClickDay}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
onScroll() {
|
onScroll() {
|
||||||
const scrollTop = getScrollTop(this.$refs.body);
|
const scrollTop = getScrollTop(this.$refs.body);
|
||||||
|
const monthsHeight = this.$refs.month.map(item => item.height);
|
||||||
let height = 0;
|
let height = 0;
|
||||||
|
|
||||||
for (let i = 0; i < this.months.length; i++) {
|
for (let i = 0; i < this.months.length; i++) {
|
||||||
@ -161,18 +170,65 @@ export default createComponent({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
height += this.monthsHeight[i];
|
height += monthsHeight[i];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onClickDay(item) {
|
onClickDay(item) {
|
||||||
if (item.disabled) {
|
const { date } = item;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.type === 'single') {
|
if (this.type === 'single') {
|
||||||
this.$emit('input', item.date);
|
this.$emit('input', date);
|
||||||
this.$emit('select', item.date);
|
this.$emit('select', date);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type === 'range') {
|
||||||
|
const startDay = this.currentValue[0];
|
||||||
|
const endDay = this.currentValue[1];
|
||||||
|
|
||||||
|
if (startDay && endDay) {
|
||||||
|
this.$emit('input', [date, null]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startDay) {
|
||||||
|
const compareWithStart = compareDay(date, startDay);
|
||||||
|
|
||||||
|
if (compareWithStart === 1) {
|
||||||
|
this.$emit('input', [startDay, date]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compareWithStart === -1) {
|
||||||
|
this.$emit('input', [date, null]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onConfirmRange() {
|
||||||
|
this.$emit('input', this.currentValue);
|
||||||
|
this.$emit('select', this.currentValue);
|
||||||
|
},
|
||||||
|
|
||||||
|
genFooter() {
|
||||||
|
if (this.type === 'range') {
|
||||||
|
const disabled = !this.currentValue[1];
|
||||||
|
const text = disabled ? this.confirmDisabledText : this.confirmText;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={bem('footer')}>
|
||||||
|
<Button
|
||||||
|
round
|
||||||
|
block
|
||||||
|
type="danger"
|
||||||
|
disabled={disabled}
|
||||||
|
class={bem('confirm')}
|
||||||
|
onClick={this.onConfirmRange}
|
||||||
|
>
|
||||||
|
{text || t('confirm')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -180,10 +236,17 @@ export default createComponent({
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div class={bem()}>
|
<div class={bem()}>
|
||||||
<Header title={this.title} currentMonth={this.currentMonth} />
|
<Header
|
||||||
|
title={this.title}
|
||||||
|
currentMonth={this.currentMonth}
|
||||||
|
scopedSlots={{
|
||||||
|
title: () => this.slots('title')
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<div ref="body" class={bem('body')} onScroll={this.onScroll}>
|
<div ref="body" class={bem('body')} onScroll={this.onScroll}>
|
||||||
{this.months.map(this.genMonth)}
|
{this.months.map(this.genMonth)}
|
||||||
</div>
|
</div>
|
||||||
|
{this.genFooter()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,14 @@
|
|||||||
.van-calendar {
|
.van-calendar {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 80vh;
|
height: 100%;
|
||||||
|
|
||||||
&-header__title,
|
&__header {
|
||||||
&-header__month,
|
flex-shrink: 0;
|
||||||
|
box-shadow: 0 2px 10px rgba(125, 126, 128, 0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header-title,
|
||||||
&__month-title {
|
&__month-title {
|
||||||
height: 44px;
|
height: 44px;
|
||||||
font-weight: @font-weight-bold;
|
font-weight: @font-weight-bold;
|
||||||
@ -14,34 +18,25 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-header {
|
&__header-title {
|
||||||
flex-shrink: 0;
|
font-size: @font-size-lg;
|
||||||
box-shadow: 0 2px 10px rgba(125, 126, 128, 0.16);
|
|
||||||
|
|
||||||
&__title {
|
|
||||||
font-size: @font-size-lg;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__month {
|
|
||||||
font-size: @font-size-md;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__weekdays {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__weekday {
|
|
||||||
flex: 1;
|
|
||||||
font-size: @font-size-sm;
|
|
||||||
line-height: 30px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__month-title {
|
&__month-title {
|
||||||
font-size: @font-size-md;
|
font-size: @font-size-md;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__weekdays {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__weekday {
|
||||||
|
flex: 1;
|
||||||
|
font-size: @font-size-sm;
|
||||||
|
line-height: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
&__body {
|
&__body {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -73,17 +68,47 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__day {
|
&__day {
|
||||||
|
position: relative;
|
||||||
width: 14.285%;
|
width: 14.285%;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
font-size: @font-size-lg;
|
font-size: @font-size-lg;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&--end,
|
||||||
|
&--start {
|
||||||
|
color: @white;
|
||||||
|
background-color: @red;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--start {
|
||||||
|
border-radius: @border-radius-md 0 0 @border-radius-md;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--end {
|
||||||
|
border-radius: 0 @border-radius-md @border-radius-md 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--middle {
|
||||||
|
color: @red;
|
||||||
|
background-color: fade(@red, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
&--disabled {
|
&--disabled {
|
||||||
color: @gray-5;
|
color: @gray-5;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__day-label {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 6px;
|
||||||
|
left: 0;
|
||||||
|
font-size: @font-size-xs;
|
||||||
|
line-height: 14px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
&__selected-day {
|
&__selected-day {
|
||||||
width: 54px;
|
width: 54px;
|
||||||
height: 54px;
|
height: 54px;
|
||||||
@ -91,4 +116,13 @@
|
|||||||
background: @red;
|
background: @red;
|
||||||
border-radius: @border-radius-md;
|
border-radius: @border-radius-md;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__footer {
|
||||||
|
padding: 7px @padding-md;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__confirm {
|
||||||
|
height: 36px;
|
||||||
|
line-height: 34px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,3 +21,23 @@ export function compareMonth(date1: Date, date2: Date) {
|
|||||||
|
|
||||||
return year1 > year2 ? 1 : -1;
|
return year1 > year2 ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function compareDay(day1: Date, day2: Date) {
|
||||||
|
const compareMonthResult = compareMonth(day1, day2);
|
||||||
|
|
||||||
|
if (compareMonthResult === 0) {
|
||||||
|
const date1 = day1.getDate();
|
||||||
|
const date2 = day2.getDate();
|
||||||
|
|
||||||
|
return date1 === date2 ? 0 : date1 > date2 ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return compareMonthResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNextDay(date: Date) {
|
||||||
|
date = new Date(date);
|
||||||
|
date.setDate(date.getDate() + 1);
|
||||||
|
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
@ -12,6 +12,10 @@ export default {
|
|||||||
confirmDelete: '确定要删除么',
|
confirmDelete: '确定要删除么',
|
||||||
telInvalid: '请填写正确的电话',
|
telInvalid: '请填写正确的电话',
|
||||||
vanCalendar: {
|
vanCalendar: {
|
||||||
|
end: '结束',
|
||||||
|
start: '开始',
|
||||||
|
title: '日期选择',
|
||||||
|
confirm: '确定',
|
||||||
weekdays: ['日', '一', '二', '三', '四', '五', '六'],
|
weekdays: ['日', '一', '二', '三', '四', '五', '六'],
|
||||||
monthTitle: (year: number, month: number) => `${year}年${month}月`
|
monthTitle: (year: number, month: number) => `${year}年${month}月`
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user