当前位置: 首页 > news >正文

如何给 wot-ui(wot-design-uni)日历里给某几天加「原点」标注 —— 实战指南

网罗开发(小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


文章目录

    • 摘要
    • 为什么用 `formatter`?它能做什么
    • 可运行 Demo(最稳方法:formatter + CSS)
      • 项目初始化(简要)
      • vite.config.ts(示例)
      • main.js / main.ts
      • App.vue (核心演示)
    • 进阶:如果你真的需要给单元格加类(更灵活)
      • DOM 操作示例(脆弱,但直接)
    • 2~3 个实际应用场景(并给出示例代码和说明)
      • 场景 A:显示“签到”小圆点(每天只显示点)
      • 场景 B:复杂事件:同一天有多个事件,点的颜色代表不同事件类型
      • 场景 C:显示“可预约”状态(灰点)并且可点击弹窗查看详情
    • 常见问题(QA)
    • 总结

摘要

最近常碰到这样的需求:日历里显示活动/签到/预约状态,希望在某些日期下方画一个小圆点来提示用户。wot-ui(wot-design-uni)的日历组件里没有“直接的 dot API”(像某些库那样的 events/attributes),但它提供了 formatter、默认插槽和 with-cell 等能力。本文把几种可行的做法按优先级讲清楚,给出可运行的 demo(基于 Vite + Vue3 + wot-design-uni),并补充 2 个实际场景示例和常见问题排查方法。文中会标注需要注意的兼容与限制,并给出可落地的代码与样式。

要点速览

  • 优选方法:利用 formatter 输出 topInfo / bottomInfo 或特殊文本,然后通过 CSS 定位并把它变成小圆点(兼容、稳定)。(wot-ui 日历文档说明了 formatter 的用法)。(wot-design-uni.pages.dev)

  • 如果你需要把 CSS 类塞进日期单元(方便灵活样式),这在官方是个可期望的功能(有 feature request),但不是所有版本都支持统一 className 字段(请看 issue)。(GitHub)

  • 兜底办法:在组件渲染后,用 DOM 查询逐个找到目标单元并插入小元素(脆弱但能兼容任意版本)。

下面逐步展开:原理 -> 代码 demo -> 场景示例 -> QA -> 总结。

为什么用 formatter?它能做什么

formatter 是 wot-ui 的日历组件提供的一个钩子:它会对每个要渲染的“日”对象调用,接收并返回一个 day 对象(包含 datetexttopInfobottomInfodisabledtype 等字段),你可以通过它改变要显示的文字或提示信息。官方文档把 formatter 作为首选的“单日定制”方案来介绍。(wot-design-uni.pages.dev)

实现“点标记”有两种思路:

  1. bottomInfotopInfo 放入一个短文本(例如 dot),然后用 CSS 把对应文本变成小圆点(样式可控、兼容性好)。

  2. 若库/版本支持,你可以把自定义类名(className)写回 day 对象,直接给单元格添加类,CSS 控制最灵活 —— 但注意:把 className 当作 API 在一些版本是 feature request(未完全稳定),请以你当前依赖版本为准。(GitHub)

下面直接给出可运行示例(Vite + Vue3),并说明如何配置与调试。

可运行 Demo(最稳方法:formatter + CSS)

说明:下面是一个完整的最小 demo,假设你使用 Vite + Vue3。示例里我们给 2025-09-202025-09-22 标注小圆点(实际中你从后端拿到日期数组)。

项目初始化(简要)

# 创建 vite + vue 项目(略):
npm init vite@latest wot-calendar-demo -- --template vue
cd wot-calendar-demo
npm install# 安装 wot-design-uni(组件库)以及辅助插件(推荐)
npm install wot-design-uni @uni-helper/vite-plugin-uni-components @dcloudio/vite-plugin-uni -D

小提示:wot-design-uni 在 Vite 下会涉及预构建与 uni 插件配置,推荐按官方文档/插件说明配置 vite.config.ts(下面给出一个推荐的 vite 配置)。有关在 Vite 中引入 uni-app 风格组件的插件参考。(uni-helper.js.org)

vite.config.ts(示例)

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Uni from '@dcloudio/vite-plugin-uni'
import Components from '@uni-helper/vite-plugin-uni-components'// 注意:Components() 应放在 Uni() 之前(官方建议)
export default defineConfig({plugins: [Components(), // 自动按需导入 wot 组件(以及其他 uni-modules)Uni(),vue()]
})

main.js / main.ts

import { createApp } from 'vue'
import App from './App.vue'// 如果需要全局样式引用(按需或手动引入)
import 'wot-design-uni/dist/style.css' // 视包内样式路径而定,若找不到请按包内路径引入createApp(App).mount('#app')

注意:项目中依赖版本差异导致路径或插件用法略有不同,按你安装的 wot-design-uni 版本调整 style 路径或导入方式。

App.vue (核心演示)

<template><div style="padding:20px;"><h3>带点标记的日历 demo(formatter + CSS)</h3><wd-calendarv-model="value":formatter="calendarFormatter"@confirm="onConfirm"/><div style="margin-top:12px">标记的日期:{{ markDates }}</div></div>
</template><script setup>
import { ref } from 'vue'// v-model 的 value(示例)
const value = ref(Date.now())// 需要点标记的日期集合(后端可以返回 yyyy-MM-dd 或 timestamp)
const markDates = ref(['2025-09-20', '2025-09-22'])// 工具:把 day.date(timestamp)转成 yyyy-MM-dd
function toYMD(ts) {const d = new Date(ts)const yyyy = d.getFullYear()const mm = (`0${d.getMonth()+1}`).slice(-2)const dd = (`0${d.getDate()}`).slice(-2)return `${yyyy}-${mm}-${dd}`
}// formatter:如果该日期在 markDates 中,就返回 bottomInfo 为特殊标记符号
const calendarFormatter = (day) => {const ymd = toYMD(day.date)if (markDates.value.includes(ymd)) {// 值得注意:bottomInfo 会作为文本渲染,我们用占位文本再用 CSS 把它做成圆点day.bottomInfo = 'dot-marker'} else {// 清空day.bottomInfo = ''}return day
}function onConfirm({ value: v }) {console.log('选中日期 timestamp:', v)
}
</script><style>
/* 下面的选择器基于 wot-design-uni 日历渲染的 DOM 结构,对于不同版本,内部类名可能略有不同,请用浏览器审查元素确认具体类。 *//* 把 bottomInfo 的文本 'dot-marker' 隐藏,用伪元素绘制一个小圆点 */
.wd-calendar .wd-calendar__cell .wd-calendar__bottom {/* 先隐藏文本(如果存在)*/color: transparent;position: relative;
}/* 在 bottom 区域用伪元素画圆点 */
.wd-calendar .wd-calendar__cell .wd-calendar__bottom::after {content: "";position: absolute;left: 50%;transform: translateX(-50%);bottom: 2px;width: 6px;height: 6px;border-radius: 50%;background: #ff5b5b; /* 点的颜色,可自定义 */display: block;
}/* 仅针对我们约定的占位文本 dot-marker 显示小圆点(避免跟其他 bottomInfo 冲突)*/
/* 如果组件没有对应可精确选择的类,需要通过更具体的 day.className 或 data-date 实现 */
.wd-calendar .wd-calendar__cell .wd-calendar__bottom {/* 如果你希望只针对 'dot-marker' 则需要添加额外选择逻辑,简单做法是把所有 bottom 区都渲染点,或者在返回 day 时也返回特定 class(见下文) */
}
</style>

解释(关键点)

  • 我们没有直接在 day 对象上写 className(因为不同版本是否支持不一)。代替方案是把 bottomInfo 设为约定值(比如 'dot-marker'),并用 CSS 把该位置替换为小圆点。这个方式稳定且和组件渲染流程天然兼容。(wot-design-uni.pages.dev)

  • 如果你确认当前版本支持把 className 写回 day(或 class 字段),那会更方便:直接 day.className = 'has-dot',再用 .has-dot .date { ... }。注意官方仓库中也有人提到希望 formatter 支持返回 className,这是一个活跃的 feature 请求(见 issue)。(GitHub)

进阶:如果你真的需要给单元格加类(更灵活)

  • 检查你当前依赖的 wot-design-uni 版本是否在 formatter 返回值上支持 className 或者 class 字段(不是所有版本都有)。

  • 如果支持:直接 day.className = 'my-dot' 并在 CSS 写 .my-dot .wd-calendar__day-number::after { ... }

  • 如果不支持:两种办法

    1. 提交 / 关注官方 issue(在官方仓库中已有人提过增加 className 的需求)。(GitHub)

    2. 采用渲染后 DOM 操作(下面示例)——不优雅但马上可用。

DOM 操作示例(脆弱,但直接)

在组件 mounted 或每次数据更新后,扫描日历 DOM,把点插入目标单元。关键点是要找出唯一标识(比如单元内时间戳或 data-xxx 属性);如果没有,就按 cell 文本和当前月份做粗匹配(容易出错)。

// 假定你已经拿到了 calendarRef(组件实例或根 DOM)
function injectDots(calendarRootEl, datesToMark) {// datesToMark: ['2025-09-20', ...]// 查找所有单元格(class 名需按你项目里实际 DOM 调整)const cells = calendarRootEl.querySelectorAll('.wd-calendar__cell')cells.forEach(cell => {// 找到显示的日期(例如 `.wd-calendar__day-number`)const numEl = cell.querySelector('.wd-calendar__day-number')if (!numEl) returnconst dayText = numEl.textContent.trim()// 根据当前面板月份计算 yyyy-mm-dd(这里要结合面板上显示的月份)const panelMonthEl = calendarRootEl.querySelector('.wd-calendar__header .month') // 伪代码// 省略计算:转换成 ymdconst ymd = computeYmdFromPanelAndDay(panelMonth, dayText)if (datesToMark.includes(ymd)) {// 防止重复插入if (!cell.querySelector('.my-dot')) {const dot = document.createElement('span')dot.className = 'my-dot'cell.appendChild(dot)}}})
}

警告:这种方式和内部 DOM 结构紧耦合,组件升级或样式改动后容易失效。仅在没有 formatter 替代时短期使用。

2~3 个实际应用场景(并给出示例代码和说明)

场景 A:显示“签到”小圆点(每天只显示点)

需求:用户签到的日期在后端返回为 ['2025-09-01', '2025-09-08'],日历在这些日期下画红点。

实现(用 formatter + bottomInfo):

  • 后端返回 signDates 数组,前端在 formatter 判断是否包含,写 bottomInfo = 'dot-marker'

  • CSS 用 bottom 区域伪元素渲染小圆点(颜色可按签到状态变)。

(前面 Demo 已展示,核心差别是 markDates 数据来源为后端 API)

场景 B:复杂事件:同一天有多个事件,点的颜色代表不同事件类型

需求:如果某日有会议画蓝点;如果有重启画橙点。

实现思路:

  • formatter 可以把 bottomInfo 设为 dot-meeting / dot-restart 或直接放一个短标识符,然后 CSS 根据值或返回的 class(如果支持)分别渲染不同颜色。

  • 推荐做法是 day.bottomInfo = 'dot-meeting' 并在 CSS 里通过 :has() 或父类选择精准匹配(若浏览器支持),或者直接在返回 day.text / topInfo 上约定并解析。

示例(伪代码):

if (eventsByDate[ymd]?.includes('meeting')) {day.bottomInfo = 'dot-meeting'
} else if (eventsByDate[ymd]?.includes('restart')) {day.bottomInfo = 'dot-restart'
}

对应 CSS:

/* meeting 小蓝点 */
.wd-calendar__bottom:contains('dot-meeting')::after { background: #2b9af3 }
/* restart 小橙点 */
.wd-calendar__bottom:contains('dot-restart')::after { background: #ff9800 }

注意:纯 CSS 没有标准的 :contains(),上面是伪写。实际做法可以借助 data-*(如果能在 day 中回写)或把占位文本作为选择钩子并隐藏文本后用 ::after。如果需要更强的条件判断,建议在 formatter 中把 day.bottomInfo 设成不同短词并在渲染后用 JS 检查并替换为对应颜色的点。

场景 C:显示“可预约”状态(灰点)并且可点击弹窗查看详情

实现:

  • formatter 标注 bottomInfo = 'dot-available'

  • 添加一个 click 监听到 calendar(组件通常提供 @select / @confirm 事件),点击可跳到预约详情或弹框。

常见问题(QA)

Q1:为什么我用了 formatter,但样式不生效?
A:可能原因有:

  • 你写的 CSS 选择器不对(不同版本的组件 DOM 结构或 class 名不同)。建议打开浏览器开发者工具,选中日历单元,看看实际 class 与结构,再按真实类名写 CSS。官方文档里 formatter 可返回 topInfo / bottomInfo,所以先确认这些 DOM 节点是否存在。(wot-design-uni.pages.dev)

Q2:为什么不能直接写 day.className
A:某些版本还没把 className 列为稳定 API(社区有相关 feature request),所以不能保证所有版本都支持。你可以查看你当前 release 的源码或 issue 记录判断是否支持。(GitHub)

Q3:我想在同一个日期显示多个小点(表示多类型事件),怎么做?
A:你可以在 bottomInfo 放一个短占位符(比如 dots:2),然后 CSS :after/::before 绘制多个小圆,通过伪元素位置与宽度布局,或者完全用自定义单元格渲染(with-cell = false 下)由你自己渲染多点结构。

Q4:如何兼容手机与小程序?
A:wot-design-uni 为 uni-app 风格组件,通常兼容小程序/APP/Web,但样式在不同平台可能略有差异(尤其 DOM 结构)。调试建议在目标平台上用平台的调试工具检查 DOM & CSS。若用 Vite 打包成 web,注意安装与预构建配置(见上文 vite 插件提示)。(uni-helper.js.org)

总结

  1. 优先使用 formatter + bottomInfo(或 topInfo)配合 CSS 绘制小圆点 —— 简单、稳定、升级风险低。(wot-design-uni.pages.dev)

  2. 如果需要更强的样式控制,尝试查看你当前库版本是否支持 className(官方 issue 有讨论);若支持直接用 day.className 最方便。(GitHub)

  3. 不建议长期依赖 DOM hack(querySelector + appendChild),仅作应急方案,因为内部类名或结构升级会导致失效。

  4. 在开发时多用浏览器 devtools 检查组件渲染(确认 bottomInfo / topInfo 在 DOM 中的呈现位置),按真实 DOM 写 CSS。

http://www.dtcms.com/a/399335.html

相关文章:

  • 网站分析培训班西安有哪些大公司
  • Vue——02 Vue指令和Vue对象的配置项
  • 商城网站模板框架购物网站如何做推广
  • html个人网站设计网络营销推广的方式都有哪些
  • 【Linux】进程概念(五) 命令行参数与环境变量的深度解析
  • 网站认领微平台公众号
  • 微盟网站模板某购物网站开发项目
  • ManualResetEvent:C# 线程同步工具
  • 手机移动端网站怎么做的第一ppt模板官网
  • C# 车牌识别系统实现
  • 国内做医疗耗材的网站宁波seo推广哪家公司好
  • vue3中返回带参数如何实现?
  • Kafka Rebalance机制全解析
  • 温州集团网站建设网站怎么做外部链接
  • 华为云产品体系选择
  • 公司网站站群是什么赣州网上商城入驻方案
  • 驱动(二)Linux 系统移植、驱动开发框架
  • LDPC码的BP译码算法(一)
  • mit6s081 lab6: copy of write fork
  • 【多尺度/局部-全局融合与优化 】涉及的工业异常检测论文摘要整理
  • CRI与容器运行时:从Kubelet到Container的最后一公里
  • cnu摄影网站chrome官网
  • 一篇了解 Git 使用方法
  • wordVSTO插件实现自动填充序号
  • 海口网站建设哪家专业灌南住房建设局网站
  • 若依框架 (Spring Boot 3) 集成 knife4j 实现 OpenAPI 文档增强
  • MySQL分库分表详解:从原理、策略到ShardingSphere中间件选型,避坑指南一篇就够了
  • Excel知识体系
  • 零基础网站建设入门到精通视频教《妻子》在线观看免费韩剧
  • AI 大模型驱动的开源知识库搭建系统 PandaWiki的网页挂件机器人教程