Calendar日历 - 图1

Calendar 日历

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

何时使用

当数据是日期或按照日期划分时,例如日程、课表、价格日历等,农历等。目前支持年/月切换。

代码演示

Calendar日历 - 图2

基本

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

  1. <template>
  2. <a-calendar v-model:value="value" @panelChange="onPanelChange" />
  3. </template>
  4. <script lang="ts">
  5. import { defineComponent, ref } from 'vue';
  6. import { Moment } from 'moment';
  7. export default defineComponent({
  8. setup() {
  9. const value = ref<Moment>();
  10. const onPanelChange = (value: Moment, mode: string) => {
  11. console.log(value, mode);
  12. };
  13. return {
  14. value,
  15. onPanelChange,
  16. };
  17. },
  18. });
  19. </script>

Calendar日历 - 图3

卡片模式

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

  1. <template>
  2. <div :style="{ width: '300px', border: '1px solid #d9d9d9', borderRadius: '4px' }">
  3. <a-calendar v-model:value="value" :fullscreen="false" @panelChange="onPanelChange" />
  4. </div>
  5. </template>
  6. <script lang="ts">
  7. import { defineComponent, ref } from 'vue';
  8. import { Moment } from 'moment';
  9. export default defineComponent({
  10. setup() {
  11. const value = ref<Moment>();
  12. const onPanelChange = (value: Moment, mode: string) => {
  13. console.log(value, mode);
  14. };
  15. return {
  16. value,
  17. onPanelChange,
  18. };
  19. },
  20. });
  21. </script>

Calendar日历 - 图4

通知事项日历

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

  1. <template>
  2. <a-calendar v-model:value="value">
  3. <template #dateCellRender="{ current: value }">
  4. <ul class="events">
  5. <li v-for="item in getListData(value)" :key="item.content">
  6. <a-badge :status="item.type" :text="item.content" />
  7. </li>
  8. </ul>
  9. </template>
  10. <template #monthCellRender="{ current: value }">
  11. <div v-if="getMonthData(value)" class="notes-month">
  12. <section>{{ getMonthData(value) }}</section>
  13. <span>Backlog number</span>
  14. </div>
  15. </template>
  16. </a-calendar>
  17. </template>
  18. <script lang="ts">
  19. import { defineComponent, ref } from 'vue';
  20. import { Moment } from 'moment';
  21. export default defineComponent({
  22. setup() {
  23. const value = ref<Moment>();
  24. const getListData = (value: Moment) => {
  25. let listData;
  26. switch (value.date()) {
  27. case 8:
  28. listData = [
  29. { type: 'warning', content: 'This is warning event.' },
  30. { type: 'success', content: 'This is usual event.' },
  31. ];
  32. break;
  33. case 10:
  34. listData = [
  35. { type: 'warning', content: 'This is warning event.' },
  36. { type: 'success', content: 'This is usual event.' },
  37. { type: 'error', content: 'This is error event.' },
  38. ];
  39. break;
  40. case 15:
  41. listData = [
  42. { type: 'warning', content: 'This is warning event' },
  43. { type: 'success', content: 'This is very long usual event。。....' },
  44. { type: 'error', content: 'This is error event 1.' },
  45. { type: 'error', content: 'This is error event 2.' },
  46. { type: 'error', content: 'This is error event 3.' },
  47. { type: 'error', content: 'This is error event 4.' },
  48. ];
  49. break;
  50. default:
  51. }
  52. return listData || [];
  53. };
  54. const getMonthData = (value: Moment) => {
  55. if (value.month() === 8) {
  56. return 1394;
  57. }
  58. };
  59. return {
  60. value,
  61. getListData,
  62. getMonthData,
  63. };
  64. },
  65. });
  66. </script>
  67. <style scoped>
  68. .events {
  69. list-style: none;
  70. margin: 0;
  71. padding: 0;
  72. }
  73. .events .ant-badge-status {
  74. overflow: hidden;
  75. white-space: nowrap;
  76. width: 100%;
  77. text-overflow: ellipsis;
  78. font-size: 12px;
  79. }
  80. .notes-month {
  81. text-align: center;
  82. font-size: 28px;
  83. }
  84. .notes-month section {
  85. font-size: 28px;
  86. }
  87. </style>

Calendar日历 - 图5

Calendar日历 - 图6

Calendar日历 - 图7

选择功能

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

  1. <template>
  2. <a-alert :message="`You selected date: ${selectedValue && selectedValue.format('YYYY-MM-DD')}`" />
  3. <div
  4. :style="{
  5. display: 'inline-block',
  6. width: '500px',
  7. border: '1px solid #d9d9d9',
  8. borderRadius: '4px',
  9. }"
  10. >
  11. <a-calendar :value="date" @select="onSelect" @panelChange="onPanelChange" />
  12. </div>
  13. <div
  14. :style="{
  15. display: 'inline-block',
  16. width: '500px',
  17. marginLeft: '20px',
  18. border: '1px solid #d9d9d9',
  19. borderRadius: '4px',
  20. }"
  21. >
  22. <a-calendar v-model:value="date1" />
  23. </div>
  24. </template>
  25. <script lang="ts">
  26. import { defineComponent, ref } from 'vue';
  27. import moment, { Moment } from 'moment';
  28. export default defineComponent({
  29. setup() {
  30. const date = ref(moment('2017-01-25'));
  31. const selectedValue = ref(moment('2017-01-25'));
  32. const date1 = ref(moment('2017-01-25'));
  33. const onSelect = (value: Moment) => {
  34. date.value = value;
  35. selectedValue.value = value;
  36. };
  37. const onPanelChange = (value: Moment) => {
  38. date.value = value;
  39. };
  40. return {
  41. date,
  42. selectedValue,
  43. date1,
  44. onSelect,
  45. onPanelChange,
  46. };
  47. },
  48. });
  49. </script>

Calendar日历 - 图8

自定义头部

自定义日历头部内容。

en-uS

Customize Calendar header content.

  1. <template>
  2. <div style="width: 300px; border: 1px solid #d9d9d9; border-radius: 4px">
  3. <a-calendar v-model:value="value" :fullscreen="false" @panelChange="onPanelChange">
  4. <template #headerRender="{ value, type, onChange, onTypeChange }">
  5. <div style="padding: 10px">
  6. <div style="margin-bottom: 10px">Custom header</div>
  7. <a-row type="flex" justify="space-between">
  8. <a-col>
  9. <a-radio-group size="small" :value="type" @change="e => onTypeChange(e.target.value)">
  10. <a-radio-button value="month">Month</a-radio-button>
  11. <a-radio-button value="year">Year</a-radio-button>
  12. </a-radio-group>
  13. </a-col>
  14. <a-col>
  15. <a-select
  16. size="small"
  17. :dropdown-match-select-width="false"
  18. class="my-year-select"
  19. :value="String(value.year())"
  20. @change="
  21. newYear => {
  22. onChange(value.clone().year(newYear));
  23. }
  24. "
  25. >
  26. <a-select-option
  27. v-for="val in getYears(value)"
  28. :key="String(val)"
  29. class="year-item"
  30. >
  31. {{ val }}
  32. </a-select-option>
  33. </a-select>
  34. </a-col>
  35. <a-col>
  36. <a-select
  37. size="small"
  38. :dropdown-match-select-width="false"
  39. :value="String(value.month())"
  40. @change="
  41. selectedMonth => {
  42. onChange(value.clone().month(parseInt(selectedMonth, 10)));
  43. }
  44. "
  45. >
  46. <a-select-option
  47. v-for="(val, index) in getMonths(value)"
  48. :key="String(index)"
  49. class="month-item"
  50. >
  51. {{ val }}
  52. </a-select-option>
  53. </a-select>
  54. </a-col>
  55. </a-row>
  56. </div>
  57. </template>
  58. </a-calendar>
  59. </div>
  60. </template>
  61. <script lang="ts">
  62. import { defineComponent, ref } from 'vue';
  63. import { Moment } from 'moment';
  64. export default defineComponent({
  65. setup() {
  66. const value = ref<Moment>();
  67. const onPanelChange = (value: Moment, mode: string) => {
  68. console.log(value, mode);
  69. };
  70. const getMonths = (value: Moment) => {
  71. const current = value.clone();
  72. const localeData = value.localeData();
  73. const months = [];
  74. for (let i = 0; i < 12; i++) {
  75. current.month(i);
  76. months.push(localeData.monthsShort(current));
  77. }
  78. return months;
  79. };
  80. const getYears = (value: Moment) => {
  81. const year = value.year();
  82. const years = [];
  83. for (let i = year - 10; i < year + 10; i += 1) {
  84. years.push(i);
  85. }
  86. return years;
  87. };
  88. return {
  89. value,
  90. onPanelChange,
  91. getMonths,
  92. getYears,
  93. };
  94. },
  95. });
  96. </script>

API

**注意:**Calendar 部分 locale 是从 value 中读取,所以请先正确设置 moment 的 locale。

  1. // 默认语言为 en-US,所以如果需要使用其他语言,推荐在入口文件全局设置 locale // import moment from
  2. 'moment'; // import 'moment/dist/locale/zh-cn'; // moment.locale('zh-cn');
  3. <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是否全屏显示booleantrue
locale国际化配置object默认配置
mode初始模式,month/yearstringmonth
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)