自定义时间范围选择组件使用教程(基于 Vue 3 + Element Plus)

🕓 自定义时间范围选择组件使用教程(基于 Vue 3 + Element Plus)

✅ 一个灵活实用的时间范围选择器,支持开始时间、结束时间、快捷时间选项、本地双向绑定、插槽扩展等功能。


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

📘 一、功能介绍

该组件基于 Element Plus<el-date-picker><el-select> 封装,支持以下特性:

  • v-model:startTimev-model:endTime 双向绑定;
  • 常用时间快捷选项:今天、昨天、本月、上月等;
  • 自定义插槽 before,可拓展前置内容;
  • 自动识别当前选择是否为快捷项并高亮;
  • 支持国际化 $t()
  • 可自定义初始选中项;
  • 样式美观、可无缝集成至查询表单。

🧱 二、组件源码

📂 components/TimeSeparation.vue

<template>

<template><slot name="before" /><el-date-pickerclass="timeSeparationClassStart"style="width:160px"v-model="startTime"type="datetime"format="YYYY-MM-DD HH:mm:ss"value-format="YYYY-MM-DD HH:mm:ss":default-time="new Date(2000, 1, 1, 0, 0, 0)" /><span class="timeSeparationClassCenter">-</span><el-date-pickerclass="timeSeparationClassEnd"style="width:160px"v-model="endTime"type="datetime"format="YYYY-MM-DD HH:mm:ss"value-format="YYYY-MM-DD HH:mm:ss":default-time="new Date(2000, 1, 1, 23, 59, 59)" /><el-select v-model="dateRangeType" class="timeSeparationClass_after" style="width:100px" @change="changeDateRange"><el-optionv-for="dict in dateList":key="dict.value":label="$t(dict.label)":value="dict.value" /></el-select>
</template>

<script setup>

<script setup>
import { useVModel } from '@vueuse/core'
import i18n from '@/i18n'
import { parseTime } from '@/utils/ruoyi'const emit = defineEmits(['update:startTime', 'update:endTime', 'change'])const props = defineProps({startTime: String,endTime: String,defaultTime: Number, // 默认快捷选中类型showAfter: { type: Boolean, default: true }
})// 双向绑定
const startTime = useVModel(props, 'startTime', emit)
const endTime = useVModel(props, 'endTime', emit)
const dateRangeType = ref(props.defaultTime)function changeDateRange(e) {switch (e) {case 1: setDaysAgo(7); break;case 2: setThisMonth(); break;case 4: setToday(); break;case 5: setYesterday(); break;case 6: setLastMonth(); break;}
}// 日期处理
function setDaysAgo(days) {const now = new Date();const start = new Date(now)start.setDate(start.getDate() - (days - 1))start.setHours(0, 0, 0, 0)now.setHours(23, 59, 59, 999)startTime.value = parseTime(start)endTime.value = parseTime(now)
}function setToday() {const now = new Date();const start = new Date(now)start.setHours(0, 0, 0, 0)now.setHours(23, 59, 59, 999)startTime.value = parseTime(start)endTime.value = parseTime(now)
}function setYesterday() {const start = new Date()const end = new Date()start.setDate(start.getDate() - 1)end.setDate(end.getDate() - 1)start.setHours(0, 0, 0, 0)end.setHours(23, 59, 59, 999)startTime.value = parseTime(start)endTime.value = parseTime(end)
}function setThisMonth() {const now = new Date()const start = new Date(now.getFullYear(), now.getMonth(), 1)const end = new Date(now.getFullYear(), now.getMonth() + 1, 0)end.setHours(23, 59, 59, 999)startTime.value = parseTime(start)endTime.value = parseTime(end)
}function setLastMonth() {const now = new Date()const start = new Date(now.getFullYear(), now.getMonth() - 1, 1)const end = new Date(now.getFullYear(), now.getMonth(), 0)end.setHours(23, 59, 59, 999)startTime.value = parseTime(start)endTime.value = parseTime(end)
}watch([() => startTime.value, () => endTime.value], ([newStart, newEnd]) => {const ranges = [{ num: 2, range: getTimeRange('本月') },{ num: 4, range: getTimeRange('今天') },{ num: 5, range: getTimeRange('昨天') },{ num: 6, range: getTimeRange('上月') },]const nowRange = [newStart, newEnd]const matched = ranges.find(i => JSON.stringify(i.range) === JSON.stringify(nowRange))dateRangeType.value = matched ? matched.num : undefinedemit('change')
})function getTimeRange(type) {const now = new Date()let start = new Date(), end = new Date()switch (type) {case '上月':start = new Date(now.getFullYear(), now.getMonth() - 1, 1)end = new Date(now.getFullYear(), now.getMonth(), 0)breakcase '本月':start = new Date(now.getFullYear(), now.getMonth(), 1)end = new Date(now.getFullYear(), now.getMonth() + 1, 0)breakcase '今天':start.setHours(0, 0, 0, 0)end.setHours(23, 59, 59, 999)breakcase '昨天':start.setDate(start.getDate() - 1)end.setDate(end.getDate() - 1)start.setHours(0, 0, 0, 0)end.setHours(23, 59, 59, 999)break}return [parseTime(start), parseTime(end)]
}const { t } = i18n.global
const dateList = [{ label: t('this_month'), value: 2 },{ label: t('today'), value: 4 },{ label: t('yesterday'), value: 5 },{ label: t('last_month'), value: 6 }
]
</script>

<style scoped lang="scss">

.timeSeparationClassCenter {display: flex;align-items: center;background-color: #fff;box-shadow:inset 0 1px 0 0 var(--el-input-border-color),inset 0 -1px 0 0 var(--el-input-border-color);
}.timeSeparationClassStart .el-input__wrapper {border-radius: var(--el-border-radius-base) 0 0 var(--el-border-radius-base);box-shadow: inset 1px 0 0 0 var(--el-input-border-color);
}.timeSeparationClassEnd .el-input__wrapper {border-radius: 0;box-shadow: inset -1px 0 0 0 var(--el-input-border-color);
}.timeSeparationClass_after .el-select__wrapper {border-radius: 0 var(--el-border-radius-base) var(--el-border-radius-base) 0;background-color: var(--el-fill-color-light);
}

🚀 三、使用示例

<template><TimeSeparationv-model:startTime="queryParams.startTime"v-model:endTime="queryParams.endTime":default-time="2"@change="onDateChange"/>
</template><script setup>
import TimeSeparation from '@/components/TimeSeparation.vue'
const queryParams = reactive({startTime: '',endTime: ''
})
function onDateChange() {console.log('时间范围变化:', queryParams)
}
</script>

📚 四、Props & Emits API 文档

Props

参数名类型默认值说明
startTimestring''外部绑定开始时间
endTimestring''外部绑定结束时间
defaultTimenumber初始选中快捷选项(如 2:本月)
showAfterbooleantrue是否显示快捷时间选择

Emits

事件名参数说明
update:startTimestring绑定用 v-model:startTime
update:endTimestring绑定用 v-model:endTime
change时间范围变更回调

🧩 五、拓展建议(可选)

拓展方向建议实现方法
动态传入快捷项增加 shortcuts: Array prop
时间范围校验内置日期合法性校验 + disabledDate
表单集成支持接入 <el-form-item> + rules
可读性文本输出增加 displayRange: computed 返回“xx 至 yy”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90159.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90159.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8 模型转换 ONNX 后 C# 调用异常:一个参数引发的跨平台适配难题

一、问题背景&#xff1a;从 Python 训练到 C# 部署的跨平台需求 作为一名 C# 开发者&#xff0c;我在完成 YOLOv8 模型训练&#xff08;使用 Ultralytics 官方框架&#xff0c;训练数据为自定义目标检测数据集&#xff0c;输入尺寸 640x640&#xff0c;训练轮次 100 轮&#…

Apache Cloudberry 亮相 2025 IvorySQL 生态大会暨 PostgreSQL 高峰论坛

6 月 27 日至 28 日&#xff0c;IvorySQL 2025 生态大会暨 PostgreSQL 高峰论坛在泉城济南顺利召开。本届大会由 IvorySQL 开源数据库社区主办、瀚高基础软件股份有限公司承办&#xff0c;吸引了来自国内外的数据库技术专家、开发者与开源爱好者齐聚一堂&#xff0c;聚焦数据库…

CMake之CMakeLists.txt语法规则

本文主要参考正点原子的应用开发手册&#xff0c;仅作为本人学习笔记使用。 目录 cmake 的使用方法其实还是非常简单的&#xff0c;重点在于编写 CMakeLists.txt&#xff0c;CMakeLists.txt 的语法规则也简单&#xff0c;并没有 Makefile的语法规则那么复杂难以理解&#xff01…

Mysql专题复习

重点内容&#xff1a;1. Mysql架构&#xff1a;客户端 Server层 存储引擎2. 索引数据结构&#xff1a;B树4. 索引优化&#xff1a;覆盖索引、排序、JOIN、分页&#xff1b; COUNT; 索引下推&#xff1b;单/双路排序5. 数据库事务&#xff1b; 锁&#xff1b;隔离级别&#xff…

CLIP的tokenizer详解

一、bytes_to_unicodedef bytes_to_unicode():"""Returns list of utf-8 byte and a corresponding list of unicode strings.The reversible bpe codes work on unicode strings.This means you need a large # of unicode characters in your vocab if you wa…

【如何判断Linux系统是Ubuntu还是CentOS】

要确定您的操作系统是 Ubuntu 还是 CentOS&#xff0c;可以通过以下方法快速检查&#xff1a; 方法 1&#xff1a;通过终端命令&#xff08;推荐&#xff09; 在终端中执行以下命令之一&#xff1a; 查看 /etc/os-release 文件 cat /etc/os-releaseUbuntu 特征&#xff1a;显示…

RISCV Linux 虚拟内存精讲系列二 -- Linux 入口 head.S

通过 Linux 的构建系统&#xff0c;即 Linux 源代码的根目录下的 Makefile&#xff0c;能够找到 vmlinux 的链接文件&#xff0c;从而能够查看其入口代码 head.S:_start&#xff0c; 如下&#xff1a; Linux 构建系统主Makefile: vmlinux.lds: head.S: 找到该入口后&#xff0c…

springAI学习:Advisors

spring AI Advisors类似于拦截器&#xff0c;会对请求的prompt做出特定的修改和增强&#xff08;比如传入历史沟通记录、搜索信息等等&#xff09;&#xff0c;以达到完善prompt的目的。通过Advisors API&#xff0c;开发人员可以创建更为复杂、可重用、可维护的AI组件。下面介…

MySQL CDC与Kafka整合指南:构建实时数据管道的完整方案

一、引言&#xff1a;现代数据架构的实时化需求 在数字化转型浪潮中&#xff0c;实时数据已成为企业的核心资产。传统批处理ETL&#xff08;每天T1&#xff09;已无法满足以下场景需求&#xff1a; 实时风险监控&#xff08;金融交易&#xff09;即时个性化推荐&#xff08;电商…

MATLAB | 绘图复刻(二十一)| 扇形热图+小提琴图

前段时间在小红书刷到了一个很有特色的热力图&#xff0c;由大佬滚筒洗衣机创作&#xff0c;感觉很有意思&#xff0c;尝试 MATLAB 复刻&#xff1a; 作者使用的是 python 代码&#xff0c;赶快去瞅瞅。 复刻效果 正文部分 0.数据准备 数据需要一个用来画热图的矩阵以及一个…

批量PDF转换工具,一键转换Word Excel

软件介绍 今天为大家推荐一款高效的Office文档批量转换工具&#xff0c;能够快速将Word和Excel文件批量转换为PDF格式。 软件特点 这款名为"五五Excel word批量转PDF"的工具体积小巧&#xff0c;不到2M大小&#xff0c;却能实现强大的批量转换功能&#xff0c…

面试150 基本计算器

思路 利用栈&#xff08;stack&#xff09;来保存进入括号前的计算状态&#xff08;包括当前计算结果和符号&#xff09;&#xff0c;以便在括号结束后正确恢复计算上下文。代码通过遍历字符串&#xff0c;识别数字、加号、减号和括号。遇到数字时构造完整数值&#xff1b;遇到…

源哈希(sh)解析

源哈希&#xff08;Source Hashing&#xff09;是一种负载均衡算法&#xff0c;它根据请求的源 IP 地址&#xff08;或其他标识符&#xff09;生成哈希值&#xff0c;然后根据这个哈希值将请求分配到特定的后端服务实例。这种方法常用于确保来自同一客户端的请求始终被路由到同…

axios的使用以及封装

前言&#xff1a; 在现代前端开发中&#xff0c;网络请求是不可避免的核心功能之一。无论是获取后端数据、提交表单信息&#xff0c;还是与第三方 API 交互&#xff0c;高效且可靠的 HTTP 请求库至关重要。axios 作为一款基于 Promise 的 HTTP 客户端&#xff0c;凭借其简洁的 …

github上部署自己的静态项目

前置知识1、要在github部署项目要提交打包后的静态文件(html,css&#xff0c;js)到仓库里2、我们看下github所提供给我们的部署方式有啥&#xff0c;如下所见&#xff1b;要么是/root文件夹&#xff08;就说仓库里全是打包后的产物&#xff1a;html,css&#xff0c;js要全部放到…

能源管理综合平台——分布式能源项目一站式监控

综合性的能源企业管理面临着项目多、分布散、信息孤岛等问题&#xff0c;分布式的多项目能源在线监控管理平台是一种集成了多个能源项目的数据采集、监控、分析和管理的系统。平台集成GIS能力&#xff0c;能够展示项目的整体分布态势&#xff0c;对不同地点、不同类型的能源项目…

修改阿里云vps为自定义用户登录

win系统上找到控制面板-->用户账户-->更改账户类型点击更改账户类型&#xff0c;此时我们看到vps的默认管理员账户Administrator。为了防止vps被别人使用默认账户Administrator攻击&#xff0c;我们添加一个用户账户&#xff0c;点击添加用户账户。 用户名建议奇葩点&…

Linux: perf: debug问题一例,cpu使用率上升大约2%;多线程如何细化cpu及perf数据分析

文章目录 前提面临的问题内核级别函数的差别继续debug总结根据pid前提 一个进程安置在一个CPU上,新功能上线之后,固定量的业务打起来,占用的CPU是42%。之前没有新功能的情况下,CPU占用是40%。差了大约2%。而且这个进程里的线程数非常多,有50多个线程。从差距看变化不大,…

计算阶梯电费

实现一个 Python 程序&#xff0c;根据使用的电量&#xff08;从控制台中让用户输入&#xff09;计算需要交的电费&#xff0c;电量分为两个阶梯&#xff0c;小于 200 度和大于 200 度&#xff0c;如果电量小于等于 200 度&#xff0c;电价就是 0.5 元/度&#xff0c;如果电量大…

替代MT6701,3D 霍尔磁性角度传感器芯片

KTH5502 是一款基于垂直霍尔技术的高精度绝对角度传感器芯片&#xff0c;支持全角度&#xff08;0–360&#xff09;测量。 芯片内部集成 X、Y 轴的垂直霍尔元件和 Z 轴的水平霍尔元件&#xff0c;能够同时感知磁场在 X、Y、Z 三个 方向的变化。得益于垂直霍尔技术优异的正交匹…