前端UI组件【免费下载链接】v-calendarAn elegant calendar and datepicker plugin for Vue.项目地址https://gitcode.com/gh_mirrors/vc/v-calendar点击查看免费下载v-calendar 是面向 Vue 的日历与日期选择器插件其attributes属性机制是组件最核心的扩展点通过一个普通的 JavaScript 对象数组开发者可以为任意单日、日期区间乃至复杂日期模式如每隔一周的周五每月 15 号附加高亮、圆点、条状标识与气泡弹窗。读完本文你将掌握属性对象的结构与全部配置项、内置色板与填充模式、order层级排序规则以及基于day-popover作用域插槽打造完全自定义弹窗的完整实战流程并了解这些能力在仓库源码中的实际落地方式。一、属性体系概述一切始于一个对象数组v-calendar通过名为attributes的 prop 接收一组装饰器对象每个对象就是一个独立的 attribute负责把视觉标记渲染到命中的日期上。属性可以作用在单个日期、日期区间也能覆盖复杂日期模式例如每隔一周的周五Every other Friday每月 15 号每隔一个月的最后一个周五属性对象的基本结构如下模板侧通过:attributes绑定数组v-calendar :attributesattributes /... data() { return { // Attributes are supplied as an array attributes: [ // This is a single attribute { // An optional key can be used for retrieving this attribute later, // and will most likely be derived from your data object key: Any, // Attribute type definitions highlight: true, // Boolean, String, Object dot: true, // Boolean, String, Object bar: true, // Boolean, String, Object content: red, // Boolean, String, Object popover: { ... }, // Only objects allowed // Your custom data object for later access, if needed customData: { ... }, // We also need some dates to know where to display the attribute // We use a single date here, but it could also be an array of dates, // a date range or a complex date pattern. dates: new Date(), // You can optionally provide dates to exclude excludeDates: null, // Think of order like z-index order: 0 } ]; } }各字段的语义如下字段类型说明keyAny通常为 String属性的唯一标识用于后续按 key 检索、驱动动画与差量更新highlightBoolean / String / Object日期背景高亮配置dotBoolean / String / Object日期下方的圆点标识barBoolean / String / Object日期底部的条状标识contentBoolean / String / Object日期内容文字的样式配置popoverObject弹窗配置仅允许对象customDataAny任意自定义数据供事件回调与插槽内容访问datesDate / Object / Array属性要覆盖的日期支持单日期、数组、区间与复杂模式excludeDatesDate / Object / Array需要排除的日期orderNumber排序优先级类似z-index默认0从源码看Attribute 类 在构造时会完成这几件事key缺省时通过createGuid()生成唯一 ID依次用主题模块归一化highlight、content、dot、bar见 theme.js用locale.normalizeDates()解析dates与excludeDates见 locale.js并记录hasDates、hasExcludeDates、excludeMode默认intersects以及isComplex是否包含复杂日期模式。1. 使用customDatacustomData用于把开发者自己的数据对象挂到属性上。典型场景是事件处理与自定义插槽内容例如用户点击了某天而这一天正展示着某个属性你希望事件回调里能拿到与该属性关联的业务数据如一条待办、一场会议就可以通过customData传递。在 CalendarDay.vue 的processPopover中customData会随弹窗事件一并透出供插槽与事件监听直接读取。2. 使用order默认情况下v-calendar会尽可能把信息展示完整当多个高亮区域重叠时单日期区域显示在日期区间区域之上起始日期较晚的区间显示在起始日期较早的区间之上。如果想要某个属性强制显示在其他属性之上、覆盖上述规则为其设置一个大于0的order值即可。这一规则的底层实现位于 CalendarDay.vuerefresh()会把当天命中的属性按a.order - b.order升序排序后依次处理因此order越大的属性越晚渲染、视觉上越靠上层。同时 AttributeStore.refresh() 在注册属性时也会读取attr.order || 0作为排序依据。二、快速上手给今天加一个高亮最简用法是给今天的日期加一个高亮背景v-calendar :attributesattrs /export default { data() { return { attrs: [ { key: today, highlight: true, dates: new Date(), }, ], }; }, };这个例子里只用了三个属性字段PropertyDescriptionkey唯一标识属性后续检索、动画、更新都会用到highlight显示在每个命中日期上的高亮区域配置dates属性显示的日期提示当highlight以及其他除 popover 外的属性类型只赋值为true时会使用当前生效的color来显示。本例没有指定colorprop因此使用默认颜色blue与默认填充模式solid。colorprop 的完整说明见 calendar API 文档。若想换成圆点标识只需把highlight换成dotexport default { data() { return { attrs: [ { key: today, dot: true, dates: new Date(), }, ], }; }, };三、颜色系统8 个内置色板与回退规则v-calendar内置了若干预定义色组gray、red、orange、yellow、green、teal、blue、indigo、purple、pink官方文档原文表述为 8 组实际列出的色名共 10 个以列表为准。颜色解析遵循以下回退链属性配置对象或字符串中显式指定的颜色优先否则使用传给v-calendar组件的colorprop若两者都未提供使用默认的blue。除 popover 外所有属性类型都可以直接指定颜色export default { data() { return { attrs: [ { key: today, highlight: red, dates: new Date(), }, ], }; }, };也可以在使用对象配置属性时把color作为配置项的一部分传入。颜色在底层被映射为 CSS 变量如var(--red-600)、var(--blue-200)具体映射逻辑见 theme.jssolid使用深色阶亮色主题下为--${color}-600light使用浅色阶--${color}-200outline使用--${color}-700作为边框色并支持暗色主题下的--${color}-500/--${color}-800等变体。四、Highlights背景高亮的三种写法与五档配置highlight可以赋值为布尔、字符串或对象三种形态// 使用当前激活颜色默认 blue highlight: true // 使用红色 highlight: red // 配置对象 highlight: { color: orange, fillMode: light, }可用的进一步定制选项如下PropertyTypeDescriptioncolorString颜色fillModeString填充方式solid默认、light、outlineclassString应用到高亮背景元素的 classstyleObject应用到高亮背景元素的 stylecontentClassString应用到高亮内容元素的 classcontentStyleObject应用到高亮内容元素的 style警告fillMode的none选项目前仍可用但将在下一个大版本中废弃推荐改用语义更清晰的outline。下面这个例子分别演示了solid、light、outline三种填充方式v-calendar :attributesattrs /data() { const date new Date(); const year date.getFullYear(); const month date.getMonth(); return { attrs: [ { key: today, highlight: { color: purple, fillMode: solid, contentClass: italic, }, dates: new Date(year, month, 12), }, { highlight: { color: purple, fillMode: light, }, dates: new Date(year, month, 13), }, { highlight: { color: purple, fillMode: outline, }, dates: new Date(year, month, 14), }, ], }; },区间高亮为 start / base / end 分段定制针对日期区间还可以分别给高亮的start起始日、base中间段与end结束日配置不同的样式v-calendar :from-page{ month: 1, year: 2019 } :attributesattrs /export default { data() { return { attrs: [ { highlight: { start: { fillMode: outline }, base: { fillMode: light }, end: { fillMode: outline }, }, dates: { start: new Date(2019, 0, 14), end: new Date(2019, 0, 18) }, }, ], }; }, };从源码层面看分段机制由 CalendarDay.vue 的processHighlight实现根据属性命中的是单日期isDate、区间起点onStart、终点onEnd、整段onStartAndEnd还是中段选择start、end或base的样式并搭配vc-day-box-center-center、vc-day-box-right-center、vc-day-box-left-center等布局容器以及vc-highlight-base-start、vc-highlight-base-end、vc-highlight-base-middle等拼接样式见 CalendarDay.vue 样式段从而在视觉上把整段区间连成一个连续的高亮带。五、Dots小巧的圆点标识dot同样支持布尔、字符串与对象三种赋值方式// 使用当前激活颜色默认 blue dot: true // 使用红色 dot: red // 配置对象 dot: { style: { backgroundColor: brown, } }dot 的可配置项相对精简PropertyTypeDescriptioncolorString颜色classString应用到 dot 元素的 classstyleObject应用到 dot 元素的 style当同一天命中多个 dot 属性时它们会在日期单元格底部横向排开。示例如下配合多列布局展示多个点叠加的效果v-calendar :columns$screens({ lg: 2 }, 1) :from-datenew Date(2018, 0, 1) :attributesattributes /export default { data() { return { attributes: [ { dot: true, dates: [ new Date(2018, 0, 1), // Jan 1st new Date(2018, 0, 10), // Jan 10th new Date(2018, 0, 22), // Jan 22nd ], }, { dot: red, dates: [ new Date(2018, 0, 4), // Jan 4th new Date(2018, 0, 10), // Jan 10th new Date(2018, 0, 15), // Jan 15th ], }, { dot: { style: { backgroundColor: brown, }, }, dates: [ new Date(2018, 0, 12), // Jan 12th new Date(2018, 0, 26), // Jan 26th new Date(2018, 0, 15), // Jan 15th ], }, ], }; }, };注意示例中的backgroundColor在实际对象写法中应写作驼峰式backgroundColor以符合浏览器样式规范。渲染层面dots 由 CalendarDay.vue 的dotsLayer生成DOM 结构为.vc-days容器内若干.vc-dot的span每个span应用主题归一化后的 class 与 style。六、Bars底部的条状标识bar同样支持三种赋值方式// 使用当前激活颜色默认 blue bar: true // 使用红色 bar: red // 配置对象 bar: { style: { backgroundColor: brown, } }bars 的配置项与 dots 完全一致PropertyTypeDescriptioncolorString颜色classString应用到 bar 元素的 classstyleObject应用到 bar 元素的 style可用性建议当同一天显示多条 bar 时它们会在单元格内等距排布。由于视觉可读性会随数量增加而下降建议每个日期格最多展示 23 条 bar。示例如下v-calendar :columns$screens({ lg: 2 }, 1) :from-datenew Date(2018, 0, 1) :attributesattributes /export default { data() { return { attributes: [ { bar: true, dates: [ new Date(2018, 0, 1), // Jan 1st new Date(2018, 0, 10), // Jan 10th new Date(2018, 0, 22), // Jan 22nd ], }, { bar: red, dates: [ new Date(2018, 0, 4), // Jan 4th new Date(2018, 0, 10), // Jan 10th new Date(2018, 0, 15), // Jan 15th ], }, { bar: { style: { backgroundColor: brown, }, }, dates: [ new Date(2018, 0, 12), // Jan 12th new Date(2018, 0, 26), // Jan 26th new Date(2018, 0, 15), // Jan 15th ], }, ], }; }, };在 CalendarDay.vue 中bars 由barsLayer渲染为.vc-bars容器下的.vc-barCSS 使用flex-grow: 1让多条 bar 自动均分宽度见 CalendarDay.vue 样式段。七、Popovers两种弹窗方案属性弹窗有两种基本实现方式标签Labels与作用域插槽Scoped Slot。1. Labels工具提示式弹窗Labels 是最基本的 tooltip 风格弹窗以普通字符串配置。默认情况下当用户将鼠标悬停在日期内容上时显示移动端为点击/触摸且弹窗内容不可交互。template v-calendar :attributesattributes / /templateexport default { data() { const todos [ { description: Take Noah to basketball practice., isComplete: false, dates: { repeat: { from: null, weekdays: 6 // Every Friday } }, color: red, }, ]; return { incId: todos.length, todos, }; }, computed: { attributes() { return [ // Attributes for todos ...this.todos.map(todo ({ dates: todo.dates, dot: { color: todo.color, class: todo.isComplete ? opacity-75 : , }, popover: { label: todo.description, }, customData: todo, })), ]; }, }, };这个例子还展示了dates的复杂模式用法——通过repeat: { weekdays: 6 }让该待办事项在每个周五重复出现日期模式的完整说明见 日期表达式文档。给popover.label赋一个字符串即告知v-calendar在悬停或移动端点击日期内容时显示该标签。若希望强制用户点击后才显示弹窗可以把popover.visibility设为focus或click... popover: { label: todo.description, visibility: focus } ...... popover: { label: todo.description, visibility: click } ...弹窗指示器Indicator你会发现弹窗内容行左侧有一个小指示器用于帮助用户把弹窗内容行与日历日期格中的标记对应起来。指示器会尽量与属性的颜色和形状保持一致——例如上面例子中使用红色圆点指示器就显示为同样的红点。如果想隐藏指示器把hideIndicator设为true... popover: { label: todo.description, visibility: hover, hideIndicator: true, } ...指示器的形状与颜色由 PopoverRow.vue 的indicator计算属性生成highlight渲染为 10×5 圆角矩形dot渲染为 5×5 圆形bar渲染为 10×3 条形颜色均取自对应属性start段的主题色。触发机制的源码实现弹窗的显隐由 popovers.js 的getPopoverTriggerEvents驱动根据visibility的值click、hover、hover-focus、focus生成绑定在日期内容上的click、mousemove、mouseleave、focusin、focusout事件再通过派发show-popover、hide-popover、toggle-popover、update-popover等document级自定义事件见 popovers.js来控制弹窗。此外CalendarDay.vue 的processPopover会为缺失的配置填充默认值当popover.label存在时默认visibility为hover、isInteractive为false无 label 时默认visibility为click、isInteractive为true。2. Scoped Slot完全自定义的day-popover对于更高级的定制可以在v-calendar内插入自定义的day-popover作用域插槽。Vue 2 中作用域插槽的写法请参考官方组件作用域插槽文档或查阅项目 demo 页面 中的实际用法示例。v-calendar :attributesattributes template #day-popover div Using my own content now /div /template /v-calendar// ...接续上面的待办示例 export default { ... computed: { attributes() { return [ // Attributes for todos ...this.todos.map(todo ({ dates: todo.dates, dot: { color: todo.color, class: todo.isComplete ? opacity-75 : , }, // 至少需要传一个 truthy 值弹窗才会出现 // 传对象可进一步定制 visibility、placement 等弹窗设置 popover: true, customData: todo, })), ]; }, }, }注意如果只是展示静态内容这个插槽帮助有限。由于插槽内容由你自己提供展示哪些属性、如何展示也需要自己处理。好在插槽作用域提供了渲染自定义数据所需的全部能力PropertyTypeDescriptiondayObject与弹窗关联的 day 对象attributesArray分配给该天的所有属性只包含popover键为 truthy 的属性formatFunction日期格式化函数分别接收date: Date与mask: String参数masksObject日历使用的格式化掩码集合updateLayoutFunction调用后强制弹窗重新计算布局例如弹窗内元素尺寸变化导致其变大或变小调用此函数可保持定位正确hideFunction调用后强制隐藏弹窗下面逐步定制之前的示例。首先加一个头部来显示弹窗对应日期v-calendar :attributesattributes template #day-popover{ day, format, masks } div classtext-xs text-gray-300 font-semibold text-center {{ format(day.date, masks.dayPopover) }} /div /template /v-calendar这里用format函数把当前day的日期按默认dayPopover掩码格式化也可以使用自定义掩码。由于这种头部展示方式很常见可以直接提取预格式化好的dayTitle属性v-calendar :attributesattributes template #day-popover{ day, dayTitle } div classtext-xs text-gray-300 font-semibold text-center {{ dayTitle }} /div /template /v-calendar接下来把当天的属性也展示出来从插槽作用域中解构attributes数组用一个简单列表渲染属性数据。v-calendar :attributesattributes div slotday-popover slot-scope{ day, dayTitle, attributes } div classtext-xs text-gray-300 font-semibold text-center {{ dayTitle }} /div ul li v-for{key, customData} in attributes :keykey {{ customData.description }} /li /ul /div /v-calendar最后如果希望在自定义内容里也显示指示器可以使用插件自带的v-popover-rowPopoverRow组件把每个属性传给它即可v-calendar :attributesattributes template #day-popover{ day, dayTitle, attributes } div div classtext-xs text-gray-300 font-semibold text-center {{ dayTitle }} /div popover-row v-forattr in attributes :keyattr.key :attributeattr {{ attr.customData.description }} /popover-row /div /template /v-calendar// 从插件导入 popover row 组件 import PopoverRow from v-calendar/lib/components/popover-row.umd.min export default { components: { PopoverRow, }, ... }3. Popover 完整选项参考以下是 属性 API 参考 中popover支持的全部配置项完整列表以该文档为准选项类型默认值说明labelStringundefined显示在弹窗内容行的文本labelClassStringundefined应用到 label 的 classlabelStyleObjectundefined应用到 label 的 stylehideDelayNumber110隐藏弹窗的延迟毫秒数v2.1.0引入hideIndicatorBooleanfalse隐藏弹窗内容行左侧的指示器isInteractiveBooleanfalse用户是否可与弹窗内容交互与同一天的其它 popover 做逻辑或合并modifiersArrayundefined用于修改 popper.js 行为的 modifiersplacementStringbottom-start弹窗的默认/建议放置位置可选auto、top、right、bottom、left并可带-start/-end后缀变体positionFixedBooleanfalse使用fixed定位显示弹窗日历位于带overflow: hidden的容器内时使用showDelayNumber0显示弹窗的延迟毫秒数v2.1.0引入transitionStringslide-fade弹窗过渡动画slide-fade、fade、none或空v2.1.0引入visibilityStringhover弹窗可见性触发方式hover-focus、hover、focus、click、visible、hidden八、源码纵深属性的生命周期与渲染分层理解属性的完整生命周期有助于排查复杂场景注册v-calendar通过 AttributeStore 接收attributes数组以key无 key 时用数组下标字符串为键维护map与listrefresh()会对每个属性做 JSON 序列化哈希hashcode只有内容变化时才重建Attribute实例实现差量更新。归一化Theme 的normalizeAttr把布尔/字符串/对象三种写法统一为{ base, start, end }三段式配置并补齐缺失的color、fillMode、style、contentStylenormalizeHighlight、normalizeDot、normalizeBar、normalizeContent分别生成对应的默认样式。仓库 tests/unit/specs/theme.spec.js 中对该归一化逻辑配有单元测试。日期解析locale.normalizeDates() 把dates/excludeDates统一包装为 DateInfo 实例单日期、区间、复杂模式on、repeat等在此被解析成startTime/endTime/isDate/isComplex等属性Attribute.intersectsDay()与includesDate()等方法见 attribute.js负责判断某天是否命中。渲染CalendarDay.vue 把日历日单元格渲染为四层结构高亮背景层vc-highlights→ 内容层day-content→ 圆点层vc-dots→ 条状层vc-bars各层均为绝对定位、pointer-events: none避免遮挡日期交互。九、总结attributes机制让v-calendar从展示日历升级为表达数据高亮承载区间与重点日圆点与条状标识适合在紧凑单元格中表达多类事件弹窗则承载明细信息——label 适合轻量提示day-popover作用域插槽适合高度定制的富内容弹窗。配合order控制层级、customData串联业务数据、复杂日期模式覆盖周期性场景足以支撑日程、待办、排班等绝大多数日历型应用。各配置项的最新完整说明可参考 属性 API 文档 与 day 对象文档。赞分享前端UI组件【免费下载链接】v-calendarAn elegant calendar and datepicker plugin for Vue.项目地址https://gitcode.com/gh_mirrors/vc/v-calendar点击查看免费下载相关推荐Vue日历组件V-Calendar完全使用指南Vue日历组件V Calendar完全使用指南 V Calendar是一个优雅、灵活的Vue.js日历和日期选择器插件为开发者提供了丰富的日期处理功能和现代化前端UI组件Classic Power Menu社区贡献指南如何参与这个开源Android项目的开发Classic Power Menu社区贡献指南如何参与这个开源Android项目的开发 Classic Power Menu是一个专为Android 11终极Vue.js日历组件v-calendar实战指南解决日期选择痛点终极Vue.js日历组件v calendar实战指南解决日期选择痛点 v calendar是一款优雅的Vue.js日历和日期选择器插件专为解决Web开发中的前端UI组件上一篇为什么ET框架的Buff系统让多个技能叠加也不会打架答案藏在事件驱动和数值组件里下一篇InternLM2.5-1.8B-Chat参数调优指南温度、top_p等超参数设置技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考