Skip to content

Calendar 日历

按照日历形式展示数据的容器。

代码演示

基础用法

一个通用的日历面板,支持年/月切换。

2025
Sep
SuMoTuWeThFrSa
31
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
01
02
03
04
05
06
07
08
09
10
11
vue
<template>
  <a-calendar v-model:value="value" @panelChange="onPanelChange" />
</template>
<script setup>
import { ref } from 'vue';
const value = ref();
const onPanelChange = (value, mode) => {
  console.log(value, mode);
};
</script>

卡片模式

用于嵌套在空间有限的容器中。

2025
Sep
SuMoTuWeThFrSa
31
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
01
02
03
04
05
06
07
08
09
10
11
vue
<template>
  <div :style="{ width: '300px', border: '1px solid #d9d9d9', borderRadius: '4px' }">
    <a-calendar v-model:value="value" :fullscreen="false" @panelChange="onPanelChange" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
const value = ref();
const onPanelChange = (value, mode) => {
  console.log(value, mode);
};
</script>

通知事项日历

一个复杂的应用示例,用 dateCellRendermonthCellRender 函数来自定义需要渲染的数据。

2025
Sep
SuMoTuWeThFrSa
31
01
02
03
04
05
06
07
08
  • This is warning event.
  • This is usual event.
09
10
  • This is warning event.
  • This is usual event.
  • This is error event.
11
12
13
14
15
  • This is warning event
  • This is very long usual event。。....
  • This is error event 1.
  • This is error event 2.
  • This is error event 3.
  • This is error event 4.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
01
02
03
04
05
06
07
08
  • This is warning event.
  • This is usual event.
09
10
  • This is warning event.
  • This is usual event.
  • This is error event.
11
vue
<template>
  <a-calendar v-model:value="value">
    <template #dateCellRender="{ current }">
      <ul class="events">
        <li v-for="item in getListData(current)" :key="item.content">
          <a-badge :status="item.type" :text="item.content" />
        </li>
      </ul>
    </template>
    <template #monthCellRender="{ current }">
      <div v-if="getMonthData(current)" class="notes-month">
        <section>{{ getMonthData(current) }}</section>
        <span>Backlog number</span>
      </div>
    </template>
  </a-calendar>
</template>
<script setup>
import { ref } from 'vue';
const value = ref();
const getListData = value => {
  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 => {
  if (value.month() === 8) {
    return 1394;
  }
};
</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>

选择功能

一个通用的日历面板,支持年/月切换。

2017
Jan
SuMoTuWeThFrSa
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
01
02
03
04
05
06
07
08
09
10
11
vue
<template>
  <a-alert :message="`You selected date: ${selectedValue && selectedValue.format('YYYY-MM-DD')}`" />
  <a-calendar :value="date" @select="onSelect" @panelChange="onPanelChange" />
</template>
<script setup>
import { ref } from 'vue';
import dayjs from 'dayjs';
const date = ref(dayjs('2017-01-25'));
const selectedValue = ref(dayjs('2017-01-25'));
const onSelect = value => {
  date.value = value;
  selectedValue.value = value;
};
const onPanelChange = value => {
  date.value = value;
};
</script>

自定义头部

自定义日历头部内容。

Custom header
2025
Sep
SuMoTuWeThFrSa
31
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
01
02
03
04
05
06
07
08
09
10
11
vue
<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: current, 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(current.year())"
                @change="
                  newYear => {
                    onChange(current.year(+newYear));
                  }
                "
              >
                <a-select-option
                  v-for="val in getYears(current)"
                  :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(current.month())"
                @change="
                  selectedMonth => {
                    onChange(current.month(parseInt(String(selectedMonth), 10)));
                  }
                "
              >
                <a-select-option
                  v-for="(val, index) in getMonths(current)"
                  :key="String(index)"
                  class="month-item"
                >
                  {{ val }}
                </a-select-option>
              </a-select>
            </a-col>
          </a-row>
        </div>
      </template>
    </a-calendar>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const value = ref();
const onPanelChange = (value, mode) => {
  console.log(value, mode);
};
const getMonths = value => {
  const localeData = value.localeData();
  const months = [];
  for (let i = 0; i < 12; i++) {
    months.push(localeData.monthsShort(value.month(i)));
  }
  return months;
};
const getYears = value => {
  const year = value.year();
  const years = [];
  for (let i = year - 10; i < year + 10; i += 1) {
    years.push(i);
  }
  return years;
};
</script>

API

TIP

Calendar 部分 locale 是从 value 中读取,所以请先正确设置 dayjs 的 locale。

vue
// 默认语言为 en-US,所以如果需要使用其他语言,推荐在入口文件全局设置 locale
// import dayjs from 'dayjs';
// import 'dayjs/locale/zh-cn';
// dayjs.locale('zh-cn');

<a-calendar v-model:value="value" @panelChange="onPanelChange" @select="onSelect"></a-calendar>
参数说明类型默认值
dateCellRender作用域插槽,用来自定义渲染日期单元格,返回内容会被追加到单元格v-slot:dateCellRender="{current: dayjs}"-
dateFullCellRender作用域插槽,自定义渲染日期单元格,返回内容覆盖单元格v-slot:dateFullCellRender="{current: dayjs}"-
disabledDate不可选择的日期(currentDate: dayjs) => boolean-
fullscreen是否全屏显示booleantrue
headerRender自定义头部内容v-slot:headerRender="{value: dayjs, type: string, onChange: f(), onTypeChange: f()}"-
locale国际化配置object默认配置
mode初始模式,month/yearstringmonth
monthCellRender作用域插槽,自定义渲染月单元格,返回内容会被追加到单元格v-slot:monthCellRender="{current: dayjs}"-
monthFullCellRender作用域插槽,自定义渲染月单元格,返回内容覆盖单元格v-slot:monthFullCellRender="{current: dayjs}"-
validRange设置可以显示的日期[dayjs, dayjs]-
value(v-model)展示日期dayjs当前日期
valueFormat可选,绑定值的格式,对 value、defaultValue 起作用。不指定则绑定值为 dayjs 对象string,具体格式-

事件

事件名称说明回调参数
change日期变化时的回调, 面板变化有可能导致日期变化function(date: dayjs | string)
panelChange日期面板变化回调function(date: dayjs | string, mode: string)
select选择日期回调,包含来源信息function(date: Dayjs, info: { source: 'year' | 'month'

如何仅获取来自面板点击的日期?

select 事件提供额外的来源信息,你可以通过 info.source 来判断来源:

vue
<script lang="ts" setup>
  const onSelect = (date, { source }) => {
    if (source === 'date') {
      console.log('Panel Select:', source);
    }
  };
</script>
<template>
  <a-calendar @select="onSelect" />
</template>