# Calendar **Category**: react **URL**: https://www.heroui.com/cn/docs/react/migration/calendar **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/migration/(components)/calendar.mdx > Calendar 从 HeroUI v2 到 v3 的迁移指南。 *** 完整的 API 参考、样式指南与高级示例请参阅 [v3 Calendar 文档](/docs/react/components/calendar)。本指南只关注从 HeroUI v2 的迁移。 ## 结构变化 在 v2 中,`Calendar` 是一个完全通过 props 配置的单一组件: ```tsx import { Calendar } from "@heroui/react"; export default function App() { return ; } ``` 在 v3 中,Calendar 改用带显式子组件的复合组件模式: ```tsx import { Calendar } from "@heroui/react"; export default function App() { return ( {(day) => {day}} {(date) => } ); } ``` ## 主要变化 ### 1. 组件结构 **v2:** 单一 `Calendar` 组件,所有布局都在内部处理 **v3:** 复合组件:`Calendar.Header`、`Calendar.Heading`、`Calendar.NavButton`、`Calendar.Grid`、`Calendar.GridHeader`、`Calendar.GridBody`、`Calendar.HeaderCell`、`Calendar.Cell`、`Calendar.CellIndicator` ### 2. 年份选择器 **v2:** 通过 `showMonthAndYearPickers` prop 提供内置月份 / 年份选择器 **v3:** 使用专用复合组件:`Calendar.YearPickerTrigger`、`Calendar.YearPickerGrid`、`Calendar.YearPickerGridBody`、`Calendar.YearPickerCell` ### 3. Prop 变更 | v2 prop | v3 等效项 | 说明 | | ------- | ----------- | ---- | | `value` | `value` | 保持一致 | | `defaultValue` | `defaultValue` | 保持一致 | | `onChange` | `onChange` | 保持一致 | | `focusedValue` | `focusedValue` | 保持一致 | | `onFocusChange` | `onFocusChange` | 保持一致 | | `minValue` | `minValue` | 保持一致 | | `maxValue` | `maxValue` | 保持一致 | | `isDateUnavailable` | `isDateUnavailable` | 保持一致 | | `isDisabled` | `isDisabled` | 保持一致 | | `isReadOnly` | `isReadOnly` | 保持一致 | | `isInvalid` | `isInvalid` | 保持一致 | | `visibleMonths` | `visibleDuration` | 改为 `{months: number}` 对象 | | `showMonthAndYearPickers` | - | 使用 `Calendar.YearPickerTrigger` 和 `Calendar.YearPickerGrid` | | `onHeaderExpandedChange` | `onYearPickerOpenChange` | 已重命名 | | `color` | - | 已移除(请改用 Tailwind CSS) | | `calendarWidth` | - | 已移除(请改用 `className` 或 Tailwind CSS) | | `weekdayStyle` | - | 已移除 | | `pageBehavior` | `pageBehavior` | 保持一致 | | `firstDayOfWeek` | - | 改用 `I18nProvider` 的 locale | | `hideDisabledDates` | - | 已移除 | | `disableAnimation` | - | 已移除 | | `topContent` | - | 将自定义内容作为 `Calendar` children 放在 `Calendar.Grid` 之前 | | `bottomContent` | - | 将自定义内容作为 `Calendar` children 放在 `Calendar.Grid` 之后 | | `classNames` | - | 在各个复合组件上使用 `className` | | `errorMessage` | - | 已移除(请在外部处理校验) | ### 4. color prop 已移除 **v2:** `color` prop 支持 `default`、`primary`、`secondary`、`success`、`warning`、`danger` **v3:** 不再提供 `color` prop,请使用 Tailwind CSS 类设置单元格样式,或通过自定义 `calendar.css` 覆盖 ## 迁移示例 ### 基本日历 ```tsx import { Calendar } from "@heroui/react"; import { today, getLocalTimeZone } from "@internationalized/date"; ``` ```tsx import { Calendar } from "@heroui/react"; import { today, getLocalTimeZone } from "@internationalized/date"; {(day) => {day}} {(date) => } ``` ### 受控状态 ```tsx import { useState } from "react"; import { Calendar } from "@heroui/react"; import { parseDate } from "@internationalized/date"; const [value, setValue] = useState(parseDate("2024-03-07")); ``` ```tsx import { useState } from "react"; import { Calendar } from "@heroui/react"; import { parseDate } from "@internationalized/date"; const [value, setValue] = useState(parseDate("2024-03-07")); {(day) => {day}} {(date) => } ``` ### 月份和年份选择器 ```tsx ``` ```tsx {(day) => {day}} {(date) => } {(year) => } ``` ### 多个月份 ```tsx ``` ```tsx
{(day) => {day}} {(date) => } {(day) => {day}} {(date) => }
```
### 不可用日期 ```tsx import { isWeekend } from "@internationalized/date"; import { useLocale } from "@react-aria/i18n"; const { locale } = useLocale(); isWeekend(date, locale)} /> ``` ```tsx import { isWeekend } from "@internationalized/date"; import { useLocale } from "@react-aria/i18n"; const { locale } = useLocale(); isWeekend(date, locale)} > {(day) => {day}} {(date) => } ``` ### 顶部与底部内容 ```tsx Select a date

} bottomContent={ } /> ```
```tsx

Select a date

{(day) => {day}} {(date) => }
```
### 单元格指示器 ```tsx {/* v2 did not have a built-in cell indicator API */} ``` ```tsx {(day) => {day}} {(date) => ( {({formattedDate}) => ( <> {formattedDate} {hasEvent(date) && } )} )} ``` ## 样式变化 ### v2:`classNames` prop ```tsx ``` ### v3:直接使用 `className` prop ```tsx {(day) => {day}} {(date) => } ``` ## 组件结构 v3 Calendar 遵循以下结构: ``` Calendar (Root) ├── [Custom top content] ├── Calendar.Header │ ├── Calendar.Heading (or Calendar.YearPickerTrigger) │ ├── Calendar.NavButton slot="previous" │ └── Calendar.NavButton slot="next" ├── Calendar.Grid (one per visible month) │ ├── Calendar.GridHeader │ │ └── Calendar.HeaderCell (render prop) │ └── Calendar.GridBody │ └── Calendar.Cell (render prop) │ └── Calendar.CellIndicator (optional) ├── Calendar.YearPickerGrid (optional) │ └── Calendar.YearPickerGridBody │ └── Calendar.YearPickerCell └── [Custom bottom content] ``` ## 总结 1. **组件结构**:单一组件 → 带显式布局控制的复合组件 2. **年份选择器**:`showMonthAndYearPickers` prop → 专用的 `Calendar.YearPickerTrigger` 和 `Calendar.YearPickerGrid` 组件 3. **多个月份**:`visibleMonths={n}` → `visibleDuration={{months: n}}`,并使用多个带 `offset` 的 `Calendar.Grid` 组件 4. **color 已移除**:请改用 Tailwind CSS 类 5. **顶部 / 底部内容**:prop 已移除 → 直接将内容作为 children 放在 `Calendar` 内 6. **单元格自定义**:新增 `Calendar.CellIndicator`,且 `Calendar.Cell` 支持渲染 prop 7. **样式**:`classNames` prop → 各个复合组件上的 `className` 8. **已移除 prop**:`calendarWidth`、`weekdayStyle`、`hideDisabledDates`、`disableAnimation` —— 请使用 Tailwind CSS 或省略