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

鸿蒙OSUniApp 实现一个精致的日历组件#三方框架 #Uniapp

使用 UniApp 实现一个精致的日历组件

前言

最近在开发一个约会小程序时,需要实现一个既美观又实用的日历组件。市面上虽然有不少现成的组件库,但都不太符合我们的设计需求。于是,我决定从零开始,基于 UniApp 自己实现一个功能完善、UI精致的日历组件。本文将分享我的实现思路和过程,希望对你有所帮助。

需求分析

首先,让我们明确一下这个日历组件需要满足的需求:

  1. 日历展示:能够清晰展示年、月、日信息
  2. 日期选择:支持单选、范围选择功能
  3. 样式定制:支持自定义主题颜色、特殊日期标记
  4. 事件标记:能够在特定日期显示事件标记或小红点
  5. 手势操作:支持左右滑动切换月份
  6. 农历展示:可选择性展示农历信息

基于以上需求,我们开始设计和编码。

实现思路

1. 数据结构设计

日历组件的核心是对日期数据的管理。我们需要设计一个合理的数据结构来存储和操作日期信息。

{year: 2023,          // 当前显示的年份month: 5,            // 当前显示的月份(1-12)day: 15,             // 当前选中的日期weeks: [             // 按周分组的日期数据[                  // 第一周{day: 30,       // 日期month: 4,      // 所属月份isCurrentMonth: false,  // 是否属于当前月isToday: false,         // 是否是今天isSelected: false,      // 是否被选中hasEvent: false,        // 是否有事件lunar: '四月初一',      // 农历信息disable: false          // 是否禁用},// ... 其他日期数据],// ... 其他周数据]
}

2. 核心功能实现

首先,我们需要计算出日历网格中的所有日期数据。这包括当前月的所有日期,以及为了填满网格而需要显示的上个月和下个月的部分日期。

以下是生成日历数据的核心函数:

/*** 生成日历数据* @param {Number} year 年份* @param {Number} month 月份(1-12)* @return {Array} 日历数据数组*/
function generateCalendarData(year, month) {// 获取当前月第一天是星期几const firstDayOfMonth = new Date(year, month - 1, 1).getDay();// 获取当前月的天数const daysInMonth = new Date(year, month, 0).getDate();// 获取上个月的天数const daysInPrevMonth = new Date(year, month - 1, 0).getDate();// 获取今天的日期信息const today = new Date();const isToday = (date) => {return date.getFullYear() === today.getFullYear() && date.getMonth() === today.getMonth() && date.getDate() === today.getDate();};// 日历数据数组let days = [];// 添加上个月的日期for (let i = 0; i < firstDayOfMonth; i++) {const prevDay = daysInPrevMonth - firstDayOfMonth + i + 1;const prevMonth = month - 1 > 0 ? month - 1 : 12;const prevYear = prevMonth === 12 ? year - 1 : year;days.push({day: prevDay,month: prevMonth,year: prevYear,isCurrentMonth: false,isToday: isToday(new Date(prevYear, prevMonth - 1, prevDay)),isSelected: false,hasEvent: false,  // 根据实际情况设置lunar: getLunarDate(prevYear, prevMonth, prevDay),  // 获取农历日期disable: false});}// 添加当前月的日期for (let i = 1; i <= daysInMonth; i++) {days.push({day: i,month,year,isCurrentMonth: true,isToday: isToday(new Date(year, month - 1, i)),isSelected: false,hasEvent: false,  // 根据实际情况设置lunar: getLunarDate(year, month, i),  // 获取农历日期disable: false});}// 添加下个月的日期,补满 6 行const totalDays = 42;  // 6行7列const remainingDays = totalDays - days.length;for (let i = 1; i <= remainingDays; i++) {const nextMonth = month + 1 <= 12 ? month + 1 : 1;const nextYear = nextMonth === 1 ? year + 1 : year;days.push({day: i,month: nextMonth,year: nextYear,isCurrentMonth: false,isToday: isToday(new Date(nextYear, nextMonth - 1, i)),isSelected: false,hasEvent: false,  // 根据实际情况设置lunar: getLunarDate(nextYear, nextMonth, i),  // 获取农历日期disable: false});}// 将日期按周分组const weeks = [];for (let i = 0; i < days.length; i += 7) {weeks.push(days.slice(i, i + 7));}return weeks;
}

3. 组件开发

接下来,让我们使用 UniApp 开发这个日历组件。我们将创建一个独立的组件,以便在不同项目中复用。

<!-- calendar.vue -->
<template><view class="calendar"><!-- 日历头部 --><view class="calendar-header"><view class="calendar-title"><text>{{ year }}年{{ month }}月</text></view><view class="calendar-controls"><view class="prev-month" @click="changeMonth(-1)"><text class="iconfont icon-left"></text></view><view class="next-month" @click="changeMonth(1)"><text class="iconfont icon-right"></text></view></view></view><!-- 星期栏 --><view class="calendar-weeks"><view class="week-item" v-for="(item, index) in weekDays" :key="index"><text :class="{'weekend': index === 0 || index === 6}">{{ item }}</text></view></view><!-- 日期网格 --><view class="calendar-days"><view class="calendar-week" v-for="(week, weekIndex) in weeks" :key="weekIndex"><viewclass="day-item"v-for="(day, dayIndex) in week":key="dayIndex":class="{'current-month': day.isCurrentMonth,'other-month': !day.isCurrentMonth,'today': day.isToday,'selected': day.isSelected,'disabled': day.disable}"@click="selectDay(day)"><view class="day-number">{{ day.day }}</view><view class="lunar-date" v-if="showLunar">{{ day.lunar }}</view><view class="event-dot" v-if="day.hasEvent"></view></view></view></view><!-- 底部操作栏 --><view class="calendar-footer" v-if="showFooter"><view class="btn-today" @click="goToToday">今天</view><view class="btn-clear" @click="clearSelection">清除</view></view></view>
</template><script>
export default {name: 'Calendar',props: {// 默认选中日期value: {type: [Date, Array],default: null},// 是否多选multiple: {type: Boolean,default: false},// 是否显示农历showLunar: {type: Boolean,default: true},// 是否显示底部操作栏showFooter: {type: Boolean,default: true},// 特殊日期,包含事件的日期events: {type: Array,default: () => []},// 主题色themeColor: {type: String,default: '#2979ff'}},data() {return {year: new Date().getFullYear(),month: new Date().getMonth() + 1,weeks: [],weekDays: ['日', '一', '二', '三', '四', '五', '六'],selectedDays: []};},watch: {value: {handler(val) {this.initSelection(val);},immediate: true},events: {handler() {this.updateCalendar();}}},created() {this.updateCalendar();},methods: {// 更新日历数据updateCalendar() {this.weeks = this.generateCalendarData(this.year, this.month);this.markEvents();this.initSelection(this.value);},// 生成日历数据generateCalendarData(year, month) {// 实现与上文相同的函数// ...},// 切换月份changeMonth(offset) {let newMonth = this.month + offset;let newYear = this.year;if (newMonth < 1) {newMonth = 12;newYear--;} else if (newMonth > 12) {newMonth = 1;newYear++;}this.year = newYear;this.month = newMonth;this.updateCalendar();},// 选择日期selectDay(day) {if (day.disable) return;if (this.multiple) {const index = this.selectedDays.findIndex(d => d.year === day.year && d.month === day.month && d.day === day.day);if (index === -1) {// 添加选中日期this.selectedDays.push({year: day.year,month: day.month,day: day.day});} else {// 取消选中this.selectedDays.splice(index, 1);}} else {// 单选模式this.selectedDays = [{year: day.year,month: day.month,day: day.day}];}// 更新选中状态this.updateSelectedStatus();// 触发事件this.$emit('input', this.getSelectedDates());this.$emit('change', this.getSelectedDates());},// 初始化选中状态initSelection(value) {if (!value) {this.selectedDays = [];} else if (Array.isArray(value)) {this.selectedDays = value.map(date => ({year: date.getFullYear(),month: date.getMonth() + 1,day: date.getDate()}));} else if (value instanceof Date) {this.selectedDays = [{year: value.getFullYear(),month: value.getMonth() + 1,day: value.getDate()}];}this.updateSelectedStatus();},// 更新选中状态updateSelectedStatus() {this.weeks = this.weeks.map(week => {return week.map(day => {const isSelected = this.selectedDays.some(d => d.year === day.year && d.month === day.month && d.day === day.day);return { ...day, isSelected };});});},// 标记事件markEvents() {if (!this.events || !this.events.length) return;this.weeks = this.weeks.map(week => {return week.map(day => {const hasEvent = this.events.some(event => {const eventDate = new Date(event.date);return eventDate.getFullYear() === day.year &&eventDate.getMonth() + 1 === day.month &&eventDate.getDate() === day.day;});return { ...day, hasEvent };});});},// 返回选中的日期对象getSelectedDates() {const dates = this.selectedDays.map(d => {return new Date(d.year, d.month - 1, d.day);});return this.multiple ? dates : dates[0] || null;},// 跳转到今天goToToday() {const today = new Date();this.year = today.getFullYear();this.month = today.getMonth() + 1;this.updateCalendar();},// 清除选择clearSelection() {this.selectedDays = [];this.updateSelectedStatus();this.$emit('input', this.multiple ? [] : null);this.$emit('change', this.multiple ? [] : null);}}
};
</script><style lang="scss">
.calendar {background-color: #fff;border-radius: 12rpx;box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);padding: 20rpx;.calendar-header {display: flex;justify-content: space-between;align-items: center;margin-bottom: 20rpx;.calendar-title {font-size: 32rpx;font-weight: bold;}.calendar-controls {display: flex;.prev-month, .next-month {width: 60rpx;height: 60rpx;display: flex;justify-content: center;align-items: center;.iconfont {font-size: 28rpx;color: #666;}}}}.calendar-weeks {display: flex;border-bottom: 1px solid #f0f0f0;padding-bottom: 10rpx;.week-item {flex: 1;text-align: center;font-size: 28rpx;color: #999;.weekend {color: #ff5252;}}}.calendar-days {.calendar-week {display: flex;margin-top: 10rpx;.day-item {flex: 1;height: 80rpx;display: flex;flex-direction: column;justify-content: center;align-items: center;position: relative;border-radius: 8rpx;&.current-month {color: #333;}&.other-month {color: #ccc;}&.today {background-color: rgba(41, 121, 255, 0.1);.day-number {font-weight: bold;}}&.selected {background-color: v-bind(themeColor);color: #fff;.lunar-date {color: rgba(255, 255, 255, 0.8);}}&.disabled {color: #ddd;cursor: not-allowed;}.day-number {font-size: 28rpx;}.lunar-date {font-size: 20rpx;color: #999;margin-top: 4rpx;}.event-dot {position: absolute;width: 8rpx;height: 8rpx;border-radius: 50%;background-color: #ff5252;bottom: 6rpx;}}}}.calendar-footer {display: flex;justify-content: flex-end;margin-top: 20rpx;.btn-today, .btn-clear {padding: 6rpx 20rpx;font-size: 24rpx;border-radius: 4rpx;margin-left: 20rpx;}.btn-today {background-color: v-bind(themeColor);color: #fff;}.btn-clear {border: 1px solid #ddd;color: #666;}}
}
</style>

农历计算

对于农历的计算,我们可以使用第三方库,比如 lunar-calendar,也可以自己实现。以下是一个简化版的农历计算函数:

function getLunarDate(year, month, day) {// 实际项目中建议使用成熟的农历库// 这里只做简单演示const lunarInfo = [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,// ... 更多农历数据];// 简化版的农历计算,实际项目中请使用完整实现const lunarDay = ['初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十','十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十','廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十'];// 模拟计算农历日期,实际使用中请使用准确算法const dayIndex = (year * 10000 + month * 100 + day) % 30;return lunarDay[dayIndex];
}

实际使用示例

下面是在实际项目中使用这个日历组件的示例:

<template><view class="container"><view class="header"><text class="title">我的日程</text></view><view class="calendar-wrapper"><Calendarv-model="selectedDate":events="eventList"themeColor="#42b983"@change="onDateChange"/></view><view class="event-list"><view class="list-title"><text>{{ formatDate(selectedDate) }}的日程</text></view><view class="empty-tip" v-if="!todayEvents.length"><text>暂无日程安排</text></view><view class="event-item" v-for="(event, index) in todayEvents" :key="index"><view class="event-time">{{ event.time }}</view><view class="event-content"><text class="event-title">{{ event.title }}</text><text class="event-desc">{{ event.description }}</text></view></view></view></view>
</template><script>
import Calendar from '@/components/calendar/calendar.vue';export default {components: {Calendar},data() {return {selectedDate: new Date(),eventList: [{date: '2023-05-15',title: '项目会议',time: '10:00',description: '讨论新功能开发计划'},{date: '2023-05-18',title: '团队建设',time: '14:00',description: '外出活动'},{date: '2023-05-22',title: '产品发布',time: '09:30',description: '新版本上线'}]};},computed: {todayEvents() {if (!this.selectedDate) return [];const dateStr = this.formatDate(this.selectedDate);return this.eventList.filter(event => event.date === dateStr);}},methods: {onDateChange(date) {console.log('选中日期变化:', date);},formatDate(date) {if (!date) return '';const year = date.getFullYear();const month = (date.getMonth() + 1).toString().padStart(2, '0');const day = date.getDate().toString().padStart(2, '0');return `${year}-${month}-${day}`;}}
};
</script><style lang="scss">
.container {padding: 30rpx;.header {margin-bottom: 30rpx;.title {font-size: 36rpx;font-weight: bold;}}.calendar-wrapper {margin-bottom: 40rpx;}.event-list {background-color: #fff;border-radius: 12rpx;padding: 20rpx;box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);.list-title {font-size: 30rpx;font-weight: bold;margin-bottom: 20rpx;color: #333;}.empty-tip {text-align: center;padding: 40rpx 0;color: #999;}.event-item {display: flex;padding: 20rpx 0;border-bottom: 1px solid #f5f5f5;&:last-child {border-bottom: none;}.event-time {width: 120rpx;color: #666;}.event-content {flex: 1;.event-title {font-size: 28rpx;color: #333;margin-bottom: 6rpx;}.event-desc {font-size: 24rpx;color: #999;}}}}
}
</style>

适配鸿蒙系统

随着华为鸿蒙系统的普及,我们也需要考虑在鸿蒙系统上的兼容性。好消息是,UniApp已经开始支持鸿蒙系统的开发。要让我们的日历组件更好地适配鸿蒙系统,可以考虑以下几点:

  1. 遵循鸿蒙设计规范:鸿蒙系统有自己的设计语言和规范,包括字体、颜色、圆角等。我们可以根据鸿蒙的设计规范调整组件样式。

  2. 性能优化:鸿蒙系统注重流畅性和低功耗,我们可以减少不必要的渲染和计算,优化日历组件的性能。

  3. 手势适配:确保日历组件的滑动等手势操作在鸿蒙系统上响应流畅。

  4. 分辨率适配:鸿蒙设备的分辨率可能有所不同,确保组件在各种分辨率下都能正常显示。

  5. 权限处理:如果日历组件需要访问系统日历数据,需要适配鸿蒙的权限管理机制。

总结与思考

通过本文,我们从零开始实现了一个功能丰富、外观精致的日历组件。这个组件具有以下特点:

  1. 灵活的日期选择:支持单选和多选模式
  2. 农历显示:可选择性显示农历信息
  3. 事件标记:能够在特定日期显示事件标记
  4. 自定义主题:支持自定义主题颜色
  5. 手势操作:支持左右滑动切换月份

当然,这个日历组件还可以进一步优化和扩展,比如:

  • 添加周视图、月视图、年视图切换功能
  • 支持日程管理,添加、编辑、删除日程
  • 增加日程提醒功能
  • 支持农历节日、法定节假日标记
  • 优化性能,减少不必要的重新渲染

希望这篇文章对你在 UniApp 开发中实现日历组件有所帮助。如果有任何问题或建议,欢迎在评论区交流讨论!

参考资料

  1. UniApp 官方文档:https://uniapp.dcloud.io/
  2. Vue.js 文档:https://cn.vuejs.org/
  3. 农历计算算法:https://github.com/jjonline/calendar.js
  4. 鸿蒙开发文档:https://developer.harmonyos.com/

相关文章:

鸿蒙OSUniApp 实现一个精致的日历组件#三方框架 #Uniapp

使用 UniApp 实现一个精致的日历组件 前言 最近在开发一个约会小程序时&#xff0c;需要实现一个既美观又实用的日历组件。市面上虽然有不少现成的组件库&#xff0c;但都不太符合我们的设计需求。于是&#xff0c;我决定从零开始&#xff0c;基于 UniApp 自己实现一个功能完…...

【爬虫】DrissionPage-3

安装&#xff1a;4.1最新版本 pip install drissionpage --upgrade 官方文档&#xff1a;&#x1f6f0;️ 连接浏览器 | DrissionPage官网 1 Chromium对象 Chromium对象用于连接和管理浏览器。标签页的开关和获取、整体运行参数配置、浏览器信息获取等都由它进行。 1.1 默认…...

Web开发-JavaEE应用SpringBoot栈SnakeYaml反序列化链JARWAR构建打包

知识点&#xff1a; 1、安全开发-JavaEE-WAR&JAR打包&反编译 2、安全开发-JavaEE-SnakeYaml反序列化&链 一、演示案例-WEB开发-JavaEE-项目-SnakeYaml序列化 常见的创建的序列化和反序列化协议 • &#xff08;已讲&#xff09;JAVA内置的writeObject()/readObje…...

项目复习(2)

第四天 高并发优化 前端每隔15秒就发起一次请求&#xff0c;将播放记录写入数据库。 但问题是&#xff0c;提交播放记录的业务太复杂了&#xff0c;其中涉及到大量的数据库操作&#xff1a;在并发较高的情况下&#xff0c;会给数据库带来非常大的压力 使用Redis合并写请求 一…...

UE 材质基础 第一天

课程&#xff1a;虚幻引擎【UE5】材质宝典【初学者材质基础入门系列】-北冥没有鱼啊_-稍后再看-哔哩哔哩视频 随便记录一些 黑色是0到负无穷&#xff0c;白色是1到无穷 各向异性 有点类似于高光&#xff0c;可以配合切线来使用&#xff0c;R G B 相当于 X Y Z轴&#xff0c;切…...

短剧小程序系统开发源码上架,短剧项目市场分析

引言 随着短视频内容消费的爆发式增长&#xff0c;短剧小程序凭借其碎片化、强互动、低成本的特点&#xff0c;成为内容创业与资本布局的新风口。2024年以来&#xff0c;行业规模突破500亿元&#xff0c;预计2027年将超千亿17。本文将深度解析短剧小程序系统开发的技术优势、市…...

学习FineBI

FineBI 第一章 FineBI 介绍 1.1. FineBI 概述 FineBI 是帆软软件有限公司推出的一款商业智能 &#xff08;Business Intelligence&#xff09; 产品 。 FineBI 是新一代大数据分析的 BI 工具 &#xff0c; 旨在帮助企业的业务人员充分了解和利用他们的数据 。FineBI 凭借强…...

Oracle日期计算跟Mysql计算日期差距问题-导致两边计算不一致

Oracle数据库对日期做加法时&#xff0c;得到的时间是某天的12:00:00 例&#xff1a; Oracle计算 select (TO_DATE(2025-04-14, YYYY-MM-DD)1.5*365) from dual; 结果&#xff1a;2026/10/13 12:00:00Mysql计算 select DATE_ADD( str_to_date( 2025-04-14, %Y-%m-%d ), INTER…...

深入剖析某App视频详情逆向:聚焦sig3参数攻克

深入剖析某手App视频详情逆向&#xff1a;聚焦sig3参数攻克 一、引言 在当今互联网信息爆炸的时代&#xff0c;短视频平台如某手&#xff0c;已成为人们获取信息、娱乐消遣的重要渠道。对于技术爱好者和研究人员而言&#xff0c;深入探索其内部机制&#xff0c;特别是视频详情…...

Java求职面试揭秘:从Spring到微服务的技术挑战

文章简述 在这篇文章中&#xff0c;我们将通过一个幽默的面试场景&#xff0c;揭秘互联网大厂Java求职者在面试中面对的技术挑战。面试官将从Spring框架、微服务架构到大数据处理等多个维度进行提问&#xff0c;并详细讲解这些技术点的应用场景和解决方案&#xff0c;帮助小白…...

【Linux】Linux安装并配置MongoDB

目录 1.添加仓库 2.安装 MongoDB 包 3.启动 MongoDB 服务 4. 验证安装 5.配置 5.1.进入无认证模式 5.2.1创建用户 5.2.2.开启认证 5.2.3重启 5.2.4.登录 6.端口变更 7.卸载 7.1.停止 MongoDB 服务 7.2.禁用 MongoDB 开机自启动 7.3.卸载 MongoDB 包 7.4.删除数…...

HANA数据库死锁

死锁是两个或多个事务相互交叉锁定的情况&#xff0c;因此任何事务都无法继续进行。 通常死锁是由应用程序设计缺陷引起的&#xff0c;但在主键约束的上下文中也可能存在更多的技术死锁&#xff08;这种情况请参考 SAP note 2429521&#xff09;。 当 HANA 数据库出现死锁时&am…...

STC32G12K128实战:串口通信

STC32G12K128芯片写一个按键通过串口1发送字符串的程序。首先&#xff0c;确认芯片的串口1配置。STC32G系列通常使用UART1&#xff0c;相关的寄存器是P_SW1来选择引脚。默认情况下&#xff0c;UART1的TX是P3.1。 接下来是设置定时器作为波特率发生器。通常用定时器2&#xff0c…...

Kotlin Multiplatform与Flutter、Compose共存:构建高效跨平台应用的完整指南

简介 在移动开发领域,跨平台技术正在重塑开发范式。Kotlin Multiplatform (KMP) 作为 JetBrains 推出的多平台开发框架,结合了 Kotlin 的简洁性与原生性能优势,使开发者能够高效共享业务逻辑。而 Flutter 凭借其高性能渲染引擎(Skia)和丰富的组件库,成为混合开发的首选方…...

ElasticSearch深入解析(十二):聚合——分桶聚合、指标聚合、管道子聚合

文章目录 一、分桶聚合1. 分桶聚合的核心逻辑与核心类型2. 分桶聚合的高级特性 二、指标聚合1. 指标聚合的核心逻辑与基础类型&#xff08;1&#xff09;基础统计指标&#xff08;单值输出&#xff09;&#xff08;2&#xff09;复合统计指标&#xff08;多值输出&#xff09; …...

spark小任务

import org.apache.spark.{Partitioner, SparkConf, SparkContext}object PartitionCustom {// 分区器决定哪一个元素进入某一个分区// 目标: 把10个分区器&#xff0c;偶数分在第一个分区&#xff0c;奇数分在第二个分区// 自定义分区器// 1. 创建一个类继承Partitioner// 2. …...

Ubuntu 20.04 报错记录: Matplotlib 无法使用 OpenCV 的 libqxcb.so

网上查了一下这个报错&#xff0c;有很多解决方案&#xff0c;但是都不是针对 OpenCV 触发的这种 qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in " */lib/*/site-packages/cv2/qt/plugins" even though it was found. 本文的方案是牺牲 …...

JS 高级程序设计 设计模式

设计模式是提升代码可维护性、可扩展性和可复用的重要工具 创建型模式 工厂模式 封装对象的创建过程&#xff0c;通过函数或类统一生成实例&#xff0c;避免直接使用 new 关键字简单工厂&#xff1a;通过函数返回不同对象实例 function createButton(type) {if (type prim…...

新电脑软件配置二:安装python,git, pycharm

安装python 地址 https://www.python.org/downloads/ 不是很懂为什么这么多版本 安装windows64位的 这里我是凭自己感觉装的了 然后cmd输入命令没有生效&#xff0c;先重启下&#xff1f; 重启之后再次验证 环境是成功的 之前是输入的python -version 命令输入错误 安装pyc…...

数据仓库:企业数据管理的核心引擎

一、数据仓库的由来 数据仓库&#xff08;Data Warehouse, DW&#xff09;概念的诞生源于企业对数据价值的深度挖掘需求。在1980年代&#xff0c;随着OLTP&#xff08;联机事务处理&#xff09;系统在企业中的普及&#xff0c;传统关系型数据库在处理海量数据分析时显露出明显瓶…...

MCU开发学习记录17* - RTC学习与实践(HAL库) - 日历、闹钟、RTC备份寄存器 -STM32CubeMX

名词解释&#xff1a; RTC&#xff1a;Real-Time Clock​ 统一文章结构&#xff08;数字后加*&#xff09;&#xff1a; 第一部分&#xff1a; 阐述外设工作原理&#xff1b;第二部分&#xff1a;芯片参考手册对应外设的学习&#xff1b;第三部分&#xff1a;使用STM32CubeMX进…...

C++中的四种强制转换

static_cast 原型&#xff1a;static_cast<type-id>(expression) type-id表示目标类型&#xff0c;expression表示要转换的表达式 static_cast用于非多态类型的转换&#xff08;静态转换&#xff09;&#xff0c;编译器隐式执行的任何类型转换都可用static_c…...

YOLOv2目标检测算法:速度与精度的平衡之道

一、YOLOv2的核心改进&#xff1a;从V1到V2的蜕变 YOLOv2作为YOLO系列的第二代算法&#xff0c;在继承V1端到端、单阶段检测的基础上&#xff0c;针对V1存在的小目标检测弱、定位精度低等问题进行了全方位升级&#xff0c;成为目标检测领域的重要里程碑。 &#xff08;一&am…...

Quic如何实现udp可靠传输

QUIC&#xff08;Quick UDP Internet Connections&#xff09;是由 Google 设计并被 IETF 标准化的传输层协议&#xff0c;它基于 UDP 实现&#xff0c;但提供了类似 TCP 的可靠性和更高级的功能&#xff08;如多路复用、0-RTT 握手、TLS 加密等&#xff09;。 尽管 UDP 是不可…...

利用腾讯云MCP提升跨平台协作效率的实践与探索

一、场景痛点 在当今这个数字化快速发展的时代&#xff0c;跨平台协作成为了许多企业和团队面临的一个重大挑战。随着企业业务的不断拓展&#xff0c;团队成员往往需要利用多种工具和平台进行沟通、协作和管理。这些平台包括但不限于电子邮件、即时通讯工具、项目管理软件、文…...

【Vue篇】数据秘语:从watch源码看响应式宇宙的蝴蝶效应

目录 引言 一、watch侦听器&#xff08;监视器&#xff09; 1.作用&#xff1a; 2.语法&#xff1a; 3.侦听器代码准备 4. 配置项 5.总结 二、翻译案例-代码实现 1.需求 2.代码实现 三、综合案例——购物车案例 1. 需求 2. 代码 引言 &#x1f4ac; 欢迎讨论&#…...

Python高级特性深度解析:从熟练到精通的跃迁之路

Python高级特性深度解析&#xff1a;从熟练到精通的跃迁之路 引言 对于已经掌握Python基础语法的开发者而言&#xff0c;如何突破瓶颈进入高手行列&#xff1f;本文将从Python的高级特性入手&#xff0c;深入剖析那些能让代码更优雅、效率更高的技术点&#xff0c;助你完成从…...

OGGMA 21c 微服务 (MySQL) 安装避坑指南

前言 这两天在写 100 天实战课程 的 OGG 微服务课程&#xff1a; 在 Oracle Linux 8.10 上安装 OGGMA 21c MySQL 遇到了一点问题&#xff0c;分享给大家一起避坑&#xff01; 环境信息 环境信息&#xff1a; 主机版本主机名实例名MySQL 版本IP 地址数据库字符集Goldengate …...

Linux面试题集合(4)

现有压缩文件:a.tar.gz存在于etc目录&#xff0c;如何解压到data目录 tar -zxvf /etc/a.tar.gz -C /data 给admin.txt创建一个软链接 ln -s admin.txt adminl 查找etc目录下以vilinux开头的文件 find /etc -name vilinux* 查找admin目录下以test开头的文件 find admin -name te…...

iOS Safari调试教程

iOS Safari调试 本教程将指导您如何使用WebDebugX调试iOS设备上的Safari浏览器。通过本教程&#xff0c;您将学习如何连接iOS设备、调试Safari中的网页、分析性能问题以及解决常见的调试挑战。 准备工作 在开始调试iOS Safari之前&#xff0c;请确保您已经&#xff1a; 安装…...