Calendar 日历
按照日历形式展示数据的容器。
何时使用
当数据是日期或按照日期划分时,例如日程、课表、价格日历等,农历等。目前支持年/月切换。
代码演示
一个通用的日历面板,支持年/月切换。
<template>
<a-calendar v-model:value="value" @panelChange="onPanelChange" />
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { Moment } from 'moment';
export default defineComponent({
setup() {
const value = ref<Moment>();
const onPanelChange = (value: Moment, mode: string) => {
console.log(value, mode);
};
return {
value,
onPanelChange,
};
},
});
</script>
用于嵌套在空间有限的容器中。
<template>
<div :style="{ width: '300px', border: '1px solid #d9d9d9', borderRadius: '4px' }">
<a-calendar v-model:value="value" :fullscreen="false" @panelChange="onPanelChange" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { Moment } from 'moment';
export default defineComponent({
setup() {
const value = ref<Moment>();
const onPanelChange = (value: Moment, mode: string) => {
console.log(value, mode);
};
return {
value,
onPanelChange,
};
},
});
</script>
一个复杂的应用示例,用 dateCellRender
和 monthCellRender
函数来自定义需要渲染的数据。
<template>
<a-calendar v-model:value="value">
<template #dateCellRender="{ current: value }">
<ul class="events">
<li v-for="item in getListData(value)" :key="item.content">
<a-badge :status="item.type" :text="item.content" />
</li>
</ul>
</template>
<template #monthCellRender="{ current: value }">
<div v-if="getMonthData(value)" class="notes-month">
<section>{{ getMonthData(value) }}</section>
<span>Backlog number</span>
</div>
</template>
</a-calendar>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { Moment } from 'moment';
export default defineComponent({
setup() {
const value = ref<Moment>();
const getListData = (value: Moment) => {
let listData;
switch (value.date()) {
case 8:
listData = [
{ type: 'warning', content: 'This is warning event.' },
{ type: 'success', content: 'This is usual event.' },
];
break;
case 10:
listData = [
{ type: 'warning', content: 'This is warning event.' },
{ type: 'success', content: 'This is usual event.' },
{ type: 'error', content: 'This is error event.' },
];
break;
case 15:
listData = [
{ type: 'warning', content: 'This is warning event' },
{ type: 'success', content: 'This is very long usual event。。....' },
{ type: 'error', content: 'This is error event 1.' },
{ type: 'error', content: 'This is error event 2.' },
{ type: 'error', content: 'This is error event 3.' },
{ type: 'error', content: 'This is error event 4.' },
];
break;
default:
}
return listData || [];
};
const getMonthData = (value: Moment) => {
if (value.month() === 8) {
return 1394;
}
};
return {
value,
getListData,
getMonthData,
};
},
});
</script>
<style scoped>
.events {
list-style: none;
margin: 0;
padding: 0;
}
.events .ant-badge-status {
overflow: hidden;
white-space: nowrap;
width: 100%;
text-overflow: ellipsis;
font-size: 12px;
}
.notes-month {
text-align: center;
font-size: 28px;
}
.notes-month section {
font-size: 28px;
}
</style>
一个通用的日历面板,支持年/月切换。
<template>
<a-alert :message="`You selected date: ${selectedValue && selectedValue.format('YYYY-MM-DD')}`" />
<div
:style="{
display: 'inline-block',
width: '500px',
border: '1px solid #d9d9d9',
borderRadius: '4px',
}"
>
<a-calendar :value="date" @select="onSelect" @panelChange="onPanelChange" />
</div>
<div
:style="{
display: 'inline-block',
width: '500px',
marginLeft: '20px',
border: '1px solid #d9d9d9',
borderRadius: '4px',
}"
>
<a-calendar v-model:value="date1" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import moment, { Moment } from 'moment';
export default defineComponent({
setup() {
const date = ref(moment('2017-01-25'));
const selectedValue = ref(moment('2017-01-25'));
const date1 = ref(moment('2017-01-25'));
const onSelect = (value: Moment) => {
date.value = value;
selectedValue.value = value;
};
const onPanelChange = (value: Moment) => {
date.value = value;
};
return {
date,
selectedValue,
date1,
onSelect,
onPanelChange,
};
},
});
</script>
自定义日历头部内容。
en-uS
Customize Calendar header content.
<template>
<div style="width: 300px; border: 1px solid #d9d9d9; border-radius: 4px">
<a-calendar v-model:value="value" :fullscreen="false" @panelChange="onPanelChange">
<template #headerRender="{ value, type, onChange, onTypeChange }">
<div style="padding: 10px">
<div style="margin-bottom: 10px">Custom header</div>
<a-row type="flex" justify="space-between">
<a-col>
<a-radio-group size="small" :value="type" @change="e => onTypeChange(e.target.value)">
<a-radio-button value="month">Month</a-radio-button>
<a-radio-button value="year">Year</a-radio-button>
</a-radio-group>
</a-col>
<a-col>
<a-select
size="small"
:dropdown-match-select-width="false"
class="my-year-select"
:value="String(value.year())"
@change="
newYear => {
onChange(value.clone().year(newYear));
}
"
>
<a-select-option
v-for="val in getYears(value)"
:key="String(val)"
class="year-item"
>
{{ val }}
</a-select-option>
</a-select>
</a-col>
<a-col>
<a-select
size="small"
:dropdown-match-select-width="false"
:value="String(value.month())"
@change="
selectedMonth => {
onChange(value.clone().month(parseInt(selectedMonth, 10)));
}
"
>
<a-select-option
v-for="(val, index) in getMonths(value)"
:key="String(index)"
class="month-item"
>
{{ val }}
</a-select-option>
</a-select>
</a-col>
</a-row>
</div>
</template>
</a-calendar>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { Moment } from 'moment';
export default defineComponent({
setup() {
const value = ref<Moment>();
const onPanelChange = (value: Moment, mode: string) => {
console.log(value, mode);
};
const getMonths = (value: Moment) => {
const current = value.clone();
const localeData = value.localeData();
const months = [];
for (let i = 0; i < 12; i++) {
current.month(i);
months.push(localeData.monthsShort(current));
}
return months;
};
const getYears = (value: Moment) => {
const year = value.year();
const years = [];
for (let i = year - 10; i < year + 10; i += 1) {
years.push(i);
}
return years;
};
return {
value,
onPanelChange,
getMonths,
getYears,
};
},
});
</script>
API
**注意:**Calendar 部分 locale 是从 value 中读取,所以请先正确设置 moment 的 locale。
// 默认语言为 en-US,所以如果需要使用其他语言,推荐在入口文件全局设置 locale // import moment from
'moment'; // import 'moment/dist/locale/zh-cn'; // moment.locale('zh-cn');
<a-calendar v-model:value="value" @panelChange="onPanelChange" @select="onSelect"></a-calendar>
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
dateCellRender | 作用域插槽,用来自定义渲染日期单元格,返回内容会被追加到单元格, | function(object: {current: moment}) | 无 | |
dateFullCellRender | 作用域插槽,自定义渲染日期单元格,返回内容覆盖单元格 | function(object: {current: moment}) | 无 | |
defaultValue | 默认展示的日期 | moment | 默认日期 | |
disabledDate | 不可选择的日期 | (currentDate: moment) => boolean | 无 | |
fullscreen | 是否全屏显示 | boolean | true | |
locale | 国际化配置 | object | 默认配置 | |
mode | 初始模式,month/year | string | month | |
monthCellRender | 作用域插槽,自定义渲染月单元格,返回内容会被追加到单元格 | function(object: {current: moment}) | 无 | |
monthFullCellRender | 作用域插槽,自定义渲染月单元格,返回内容覆盖单元格 | function(object: {current: moment}) | 无 | |
validRange | 设置可以显示的日期 | [moment, moment] | 无 | |
value(v-model) | 展示日期 | moment | 当前日期 | |
headerRender | 自定义头部内容 | function(object:{value: moment, type: string, onChange: f(), onTypeChange: f()}) | v-slot | - | 1.5.0 |
valueFormat | 可选,绑定值的格式,对 value、defaultValue 起作用。不指定则绑定值为 moment 对象 | string,具体格式 | - | 1.5.4 |
事件
事件名称 | 说明 | 回调参数 |
---|---|---|
panelChange | 日期面板变化回调 | function(date: moment | string, mode: string) |
select | 点击选择日期回调 | function(date: moment | string) |
change | 日期变化时的回调, 面板变化有可能导致日期变化 | function(date: moment | string) |