ElementPlus徽章组件:展示日期面板每天未完成的待办数量

目录

一.el-badge组件、日期选择器

1.核心前端代码

2.el-badge徽章组件

3.el-date-picker日期选择器

4.核心js代码

二.核心SQL

三.效果展示


技术栈:

①前端VUE

②前端组件库ElementPlus

③后端Springboot

④数据库Mysql

一.el-badge组件、日期选择器

1.核心前端代码

html 复制代码
<el-date-picker
    v-model="todoDate"
    type="date"
    placeholder="您要查看哪一天的待办?"
    style="width: 200px;"
    @change="changeDay"
    @panel-change="changeMonth"
    clearable
>
    <!-- 自定义插槽 -->
    <template #default="{date}">
        <el-badge 
        :value="unfinishedTask.find(item => item.myDay === (date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0')))?.unfishedCount || 0"    
        class="item" 
        :offset="[8, 5]" 
        :is-dot="false" 
        :hidden="!unfinishedTask.some(item => item.myDay === (date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0')))"
        >
            <!-- <span>{{ date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0') }}</span> -->
            <span>{{date.getDate()}}</span>
        </el-badge>
    </template>
</el-date-picker>

2.el-badge徽章组件

value:小红点的数字

offset:小红点的偏移量(可以进行位置微调)

is-dot:为true就只展示小红点;为false可以额外展示数字

hidden:为true就隐藏红点

3.el-date-picker日期选择器

主要理解以下两点:

①自定义插槽<template #default></template>,只有使用这个插槽时,才能给日期面板的每日单元格添加徽章组件,不然你这个el-badge徽章都不知道加在哪里;说白了这个插槽,就代表了每一天的那个单元格。

②@change事件,在日期被切换时触发(比如从2026-01-01切到了2026-01-02号),由于日期切换时,可能直接跨月份,所以需要查询最新月份的每日未完成待办数量;

③@panel-change事件,在日期面板被切换时触发(比如从2025的12月,切换到了2026的1月),我们在这个方法中,查询当前月的每日未完成待办数;

4.核心js代码

javascript 复制代码
//变量11:当前日期面板所处的月份(举例:2026-01),初始值就是今天所处的年月
const panelMonth = ref(new Date().getFullYear() + '-' + String(new Date().getMonth() + 1).padStart(2, '0'));
//变量12:渲染日期选择器的小红点的对象
const unfinishedTask = ref([]);


//方法14:查询当前月份每天未完成的待办数量
const queryUnfinishedCount = async()=>{
    //1.构建入参
    const req = {
        userId:user.id,
        time:panelMonth.value
    }
    //2.发送请求
    const res = await getUnFinishedCount(req);
    unfinishedTask.value = res.data;
    //3.预览响应结果
    //alert(panelMonth.value)
    //alert(JSON.stringify(unfinishedTask.value));

}
queryUnfinishedCount();

//方法15:切换月份时(比如从2025年11月切到了2025年12月),要重新查询12月的每天未完成待办数(因为旧数据是11月的每天未完成代办数)
//说白了就是:当日期面板发生变化时,触发的函数
const changeMonth = async(Date)=>{
    //1.更新当前日期面板月份panelMonth(变量11)
    const year = Date.getFullYear();
    const month = Date.getMonth() + 1; // getMonth()返回0-11,需要+1
    panelMonth.value = `${year}-${month.toString().padStart(2, '0')}`;
    //alert(panelMonth.value)
    //2.重新查询当前日期面板所有天的未完成待办数
    queryUnfinishedCount();
}

//方法16:日期变化时,触发的事件
const changeDay = (Date)=>{
    //1、更新待办列表
    doQuery();
    //2、更新日期面板未完成待办数
    //2-1更新日期面板月份
    const year = Date.getFullYear();
    const month = Date.getMonth() + 1; // getMonth()返回0-11,需要+1
    panelMonth.value = `${year}-${month.toString().padStart(2, '0')}`;
    //alert(panelMonth.value);
    //2-2重新查询当前日期面板所有天的未完成待办数
    queryUnfinishedCount();
}

二.核心SQL

java 复制代码
@Select("SELECT " +
        "    DATE(create_time) AS myDay, " +
        "    COUNT(*) AS unfishedCount " +
        "FROM todo_task " +
        "WHERE " +
        "    user_id = #{userId} AND " +
        "    is_deleted = 0 AND " +
        "    status IN ('0', '1') AND " +
        "    DATE_FORMAT(create_time, '%Y-%m') IN ( " +
        "        DATE_FORMAT(STR_TO_DATE(CONCAT(#{time}, '-01'), '%Y-%m-%d') - INTERVAL 1 MONTH, '%Y-%m'), " +
        "        #{time}, " +
        "        DATE_FORMAT(STR_TO_DATE(CONCAT(#{time}, '-01'), '%Y-%m-%d') + INTERVAL 1 MONTH, '%Y-%m') " +
        "    ) " +
        "GROUP BY DATE(create_time)")
public List<Map> getUnFinishedCount(GetUnFinishedCountDto dto);

代码解读:

这个 SQL 查询用于统计用户在指定月份及其前后一个月 中,每天的未完成任务数量

主要逻辑:

1、查询目标

  • 按日期分组,统计每个日期有多少个未完成的任务
  • myDay:任务创建日期(仅日期部分)
  • unfishedCount:该日期未完成的任务数量

2、筛选条件

  • user_id = #{userId}:指定用户

  • is_deleted = 0:未删除的任务

  • status IN ('0', '1'):状态为 '0' 或 '1'(代表未完成状态)

  • 时间范围:#{time} 参数指定的月份以及前一个月和后一个月(可弥补前端日期面板不显示非当月未完成待办数的缺陷、提高查询效率)

3、时间范围逻辑

  • #{time} 参数格式应为 'YYYY-MM'(如:'2024-01'

  • 通过 CONCAT(#{time}, '-01') 补全为完整日期

  • 使用 - INTERVAL 1 MONTH+ INTERVAL 1 MONTH 获取前后月份

  • 最终查询 三个月 的数据(前月 + 本月 + 后月)


示例说明:

假设参数为 #{time} = '2024-01',则查询的时间范围包括:

  • 2023年12月(前一个月)

  • 2024年1月(本月)

  • 2024年2月(后一个月)


返回结果示例:

复制代码
[
  {"myDay": "2023-12-15", "unfishedCount": 5},
  {"myDay": "2023-12-16", "unfishedCount": 3},
  {"myDay": "2024-01-10", "unfishedCount": 8},
  ...
]

三.效果展示

本篇文章只是给出了核心代码和思路,具体感兴趣可以自己动手试一试。

以上就是本篇文章的全部内容,喜欢的话可以留个免费的关注呦~~~

相关推荐
想做后端的前端7 小时前
WebGL实现FPS游戏
vue.js·游戏·webgl
英勇无比的消炎药11 小时前
TinyRobot v0.5.0 深度解读(三):Layout 组件——如何组织复杂工作区的页面布局
前端·vue.js
英勇无比的消炎药11 小时前
TinyRobot v0.5.0 深度解读(四):CLI 脚手架——从零搭建 AI 应用的工程化实践
前端·vue.js·github
李明卫杭州12 小时前
Vue3 响应式概念 ↔ React 对应方案(类组件与函数组件)对照笔记
前端·vue.js·react.js
英勇无比的消炎药12 小时前
拖文件进来会发生什么:TinyRobot DragOverlay 与 v-dropzone 协同指南
vue.js
Revolution6112 小时前
reactive 对象重新赋值后,表单为什么没有恢复默认值
前端·vue.js·面试
sugar__salt13 小时前
Vue3 核心特性深度解析:v-model、ref 属性与 nextTick 完全指南
前端·javascript·vue.js·前端框架·vue
古韵13 小时前
你的 uni-app 分页,一个 hook 搞定竞态和加载
javascript·vue.js·uni-app
亦暖筑序15 小时前
AgentScope-Java 入门:完善 Vue 前端、发布 GitHub,并规划下一步
java·前端·vue.js