基于UniApp与Vue3的工作日历组件实战:跨端周计划与日报管理方案

张开发
2026/4/14 15:04:42 15 分钟阅读

分享文章

基于UniApp与Vue3的工作日历组件实战:跨端周计划与日报管理方案
1. 为什么选择UniAppVue3开发工作日历组件最近在做一个企业OA系统的升级项目客户明确要求要在微信小程序、H5和原生App上实现统一的工作日历功能。经过技术选型最终选择了UniAppVue3的组合方案这里分享一下我的实战经验。首先说说为什么选择这个技术栈。UniApp的跨端能力确实强大一套代码可以同时发布到多个平台这对需要覆盖多终端的企业应用来说简直是刚需。而Vue3的组合式APIComposition API在处理复杂业务逻辑时比Vue2的Options API更加灵活和清晰。在实际开发中我发现这个组合有几个特别实用的优势开发效率高使用Vue3的setup语法糖代码组织更加模块化性能优化明显Vue3的响应式系统重写后在移动端表现更流畅维护成本低组合式API让业务逻辑聚合性更好不像以前要分散在各个生命周期里2. 核心功能设计与实现思路2.1 周计划与日报的数据结构设计这个组件的核心是要同时处理周计划和日报两种数据数据结构设计很关键。经过几次迭代我最终采用了这样的结构const planList [{ planId: 1, beginDate: 2023-10-02, // 周开始日期 endDate: 2023-10-08, // 周结束日期 weekWorkPlan: 本周工作计划内容..., // 每日状态 mondayStatus: 0, // 0未提交 1审核中 2已通过 mondayIsHoliday: false, tuesdayStatus: 1, tuesdayIsHoliday: false, // ...其他日期 }]这种设计有几个考虑按周组织数据符合企业周报习惯每日状态独立存储方便单独操作包含节假日标识方便特殊显示2.2 日历渲染的核心算法日历组件的核心难点在于日期计算和渲染。我参考了uni-calendar的实现但做了大量优化// 获取某月的周数据 _getMonthWeeks(year, month) { // 计算当月第一天是周几 const firstDay new Date(year, month-1, 1).getDay() // 调整为周一作为每周第一天 const adjustedFirstDay firstDay 0 ? 6 : firstDay - 1 // 计算当月天数 const daysInMonth new Date(year, month, 0).getDate() // 构建完整日历数组包含上月尾和下月头 let days [] // 添加上月末尾几天 days days.concat(this._getLastMonthDays(adjustedFirstDay)) // 添加当月天数 days days.concat(this._currentMonthDays(daysInMonth)) // 补充下月开头几天 days days.concat(this._getNextMonthDays(42 - days.length)) // 按周分组 let weeks [] for(let i0; idays.length; i7){ const weekDays days.slice(i, i7) // 查找对应的周计划数据 const weekPlan this._findWeekPlan(weekDays[0].date) weeks.push({ days: weekDays, plan: weekPlan }) } return weeks }这个算法确保了日历总是显示6行42天避免跳动正确显示上月剩余和下月开始日期高效匹配周计划数据3. 跨平台适配的关键技巧3.1 多端样式适配方案UniApp虽然号称一次编写多端运行但实际开发中还是需要处理一些平台差异。对于日历组件我总结了这些适配经验尺寸单位统一使用rpx在uni-app中rpx会根据屏幕宽度自适应缩放平台条件编译针对特殊平台做样式微调/* 通用样式 */ .calendar-day { width: 100rpx; height: 100rpx; } /* 微信小程序特有样式 */ /* #ifdef MP-WEIXIN */ .calendar-day { border-radius: 8rpx; } /* #endif */ /* H5特有样式 */ /* #ifdef H5 */ .calendar-day { cursor: pointer; } /* #endif */3.2 性能优化实践在低端Android设备上测试时发现日历滚动时有卡顿。通过排查发现主要瓶颈在大量DOM操作上。最终采用的优化方案虚拟滚动只渲染可视区域内的日期数据分页按月加载数据避免一次性处理过多数据减少响应式数据将静态数据标记为普通对象// 使用shallowRef减少响应式开销 const weeks shallowRef([]) // 按月加载数据 async function loadMonthData(year, month) { loading.value true // 只请求当月数据 const data await fetchMonthPlans(year, month) // 手动合并数据避免响应式代理整个数组 weeks.value mergeWeekData(weeks.value, data) loading.value false }4. 企业级功能扩展实现4.1 审批流程集成很多企业需要日报/周报的审批功能。我们通过扩展组件props实现了灵活的审批状态控制// 组件props定义 const props defineProps({ // 是否需要审批流程 needApprove: { type: Boolean, default: false }, // 当前用户的审批权限 canApprove: { type: Boolean, default: false }, // 审批状态映射 statusMap: { type: Object, default: () ({ 0: { text: 未提交, color: #999 }, 1: { text: 审核中, color: #FF9900 }, 2: { text: 已通过, color: #07C160 } }) } })在模板中根据状态显示不同UIview v-ifneedApprove :style{ color: statusMap[day.status].color } {{ statusMap[day.status].text }} /view4.2 多语言与本地化支持对于跨国企业用户我们增加了多语言和本地化支持日期格式化使用uni-app的i18n API节假日数据内置常见国家的节假日配置周起始日支持周一或周日作为一周开始// 根据地区设置周起始日 const weekStart computed(() { return i18n.locale zh-CN ? 1 : 0 // 中国周一欧美周日 }) // 节假日判断 function isHoliday(date) { const localeHolidays holidays[i18n.locale] || [] return localeHolidays.includes(date) }5. 实际开发中的坑与解决方案5.1 微信小程序的DOM限制在微信小程序上遇到了一个棘手问题z-index层级问题导致日历弹窗被遮挡。经过排查发现是小程序的DOM渲染机制导致的。最终解决方案/* 使用wxss特有的z-index方案 */ /* #ifdef MP-WEIXIN */ .calendar-popup { position: fixed; z-index: 9999; /* 普通CSS */ elevation: 9999; /* 小程序专用属性 */ } /* #endif */5.2 iOS日期解析差异在测试中发现iOS和Android对Date对象的解析存在差异// Android和iOS表现不一致 new Date(2023-10-01) // 解决方案使用/分隔符 new Date(2023/10/01)这个坑让我花了半天时间调试记录在此希望大家避免。6. 组件封装与发布建议6.1 合理的props设计一个好的组件应该提供足够的灵活性同时保持简单易用。我们的props设计原则基础显示控制showPlan/showDay等布尔值控制显隐数据注入通过planList传入数据事件回调只提供必要的事件如dateClick/weekClick样式定制通过CSS变量暴露关键样式点defineProps({ // 基础控制 showPlan: Boolean, showDay: Boolean, // 数据 planList: { type: Array, default: () [] }, // 样式定制 themeColor: { type: String, default: #007AFF } })6.2 发布到uni-app插件市场为了让更多开发者受益我们将组件发布到了uni-app插件市场。发布时注意完整文档包括props、events、slots说明示例项目提供可直接运行的demo版本兼容明确支持的uni-app版本开源协议选择合适的开源协议7. 企业落地案例与效果在某大型制造企业的OA系统中落地后这个工作日历组件带来了显著效果提报效率提升周报提报时间从平均15分钟缩短到5分钟审批流程透明员工可以实时查看审批状态多端体验一致PC、手机、平板体验高度统一节假日管理HR可以提前配置节假日自动提醒客户反馈最满意的是周计划和日报的联动设计以及流畅的跨平台体验。这也验证了我们技术选型的正确性。8. 未来扩展方向虽然组件已经满足基本需求但还有不少可以增强的地方团队协作视图查看团队成员的工作安排与会议系统集成直接从日历创建会议数据分析自动生成工作投入报告离线支持在网络不稳定时也能正常使用这些功能已经在我们的迭代计划中后续会根据客户需求逐步实现。

更多文章