关键在于明确插槽位置、数量及职责:标题栏(header)、周起始标识(weekdays)、日期单元格(date-cell)、底部操作区(footer)四类插槽各司其职,均需提供作用域数据与默认实现,并通过 provide/inject 实现跨层级状态共享。

关键不在“怎么写 slot”,而在“在哪留 slot、留几个、各自承担什么职责”。插槽本质是把不确定的 UI 结构交给使用者决定,组件只管数据逻辑、交互控制与基础布局。
聚焦 4 类可定制区域
一个实用的日期选择器面板通常需拆分为以下四类插槽,职责分明、互不干扰:
-
标题栏(header):支持自定义年月切换按钮、标题文字、“今天”“清空”等操作。建议用具名插槽
slot="header",透出当前年月和切换方法(如prevMonth()、nextYear())。 -
周起始标识(weekdays):用于替换周一到周日的显示内容(如中文/英文/emoji)。用作用域插槽暴露
{ day: 'Mon', index: 0 }等结构化数据,便于按需渲染。 -
日期单元格(date-cell):最核心的定制点。必须提供完整上下文,例如:
{ date, isCurrentMonth, isToday, isSelected, isDisabled, isInRange }。避免只传原始 Date 对象,应由组件内部预计算好状态再透出。 -
底部操作区(footer):放置确认/取消按钮或自定义提交逻辑。插槽内应可直接访问选中值和提交方法(如
submit()),无需重复取值或手动 emit。
用作用域插槽传递精确状态
不要让使用者重复判断业务逻辑。比如日期单元格,若只传 date,用户还得自己调用 isBeforeToday() 或比对禁用规则——这违背封装初衷。
正确做法是组件内部统一计算并透出状态对象:
- 根据
disabledDate函数判断是否禁用; - 结合
modelValue和range判断是否在选中范围内; - 基于当前系统时间标记是否为今日;
- 最终合并为一个
state对象,供插槽直接消费。
保留默认行为,但允许完全接管
每个插槽都必须有合理默认实现,确保不传插槽时组件仍可用:
- 不传
date-cell→ 渲染纯数字 + 基础样式(今日加粗、禁用置灰); - 一旦传入 → 组件仅提供基础容器(如带定位和尺寸的
<div>),交出全部渲染与交互控制权; <li>其他插槽同理:header 默认显示“2026 年 4 月”,weekdays 默认显示“日 一 二…”,footer 默认放“确定”“取消”按钮。</li> <h3>跨层级状态共享推荐 provide/inject</h3> <p>当插槽嵌套较深(如 footer 中的按钮需触发 header 的跳转逻辑),用 <code>provide/inject比 props 层层透传更简洁可靠。例如在根组件中
provide('datePickerContext', { date, gotoMonth, submit }),各插槽内部均可inject('datePickerContext')获取,无需关心层级关系。









