Vue3日期选择器(DatePicker)-程序员宅基地

技术标签: Vue3  vue  less  typescript  ts  

本组件基 @vuepic/vue-datepicker@^7.4.1 插件进行了二次封装,以便更适合日常使用!

官方文档:https://vue3datepicker.com/installation/

除了范围选择器、年选择器以外,其余选择的日期(v-model:date)均默认返回字符串指定格式日期!

可自定义设置以下二次封装属性(也可根据官方文档设定相应属性,组件已设置继承所有属性):

  • 日期选择器宽度(width),类型:number,单位px,默认 180

  • 选择器模式(mode),类型:'time'|'date'|'week'|'month'|'year',默认 'date',可选:时间time,日期date,周week,月month,年year

  • 是否增加时间选择(showTime),类型:boolean,默认 false

  • 是否展示”今天“按钮(showToday),类型:boolean,默认 false

  • v-model值的类型(modelType),类型:'timestamp'|'format',默认 'format',可选时间戳(timestamp)、字符串(format),mode为week和year时,该配置不生效

更多使用方式还请查阅官方文档,功能设计非常全面,各部分主题颜色也均可自定义修改!

常用官方属性举例:

  • 日期展示格式(format),类型:string,默认 'yyyy-MM-dd',可选(y: 年, M: 月, d: 天, H: 时, m: 分, s: 秒)

  • 范围选择器是否使用双日期面板(multiCalendars),类型:boolean,默认 false

  • 定义选择顺序(flow),类型:array,默认 [],可选 ("calendar" | "time" | "month" | "year" | "minutes" | "hours" | "seconds")[]

  • 样式主题是否使用黑色(dark),类型:boolean,默认 false

  • 是否展示秒选择(enable-seconds),类型:boolean,默认 false

效果如下图:在线预览

①创建日期选择器组件DatePicker.vue:

<script lang="ts">
/*
  一个根节点时,禁用组件根节点自动继承 attribute,必须使用这种写法!然后在要继承 attribute 的节点上绑定 v-bind="$attrs" 即可
  多个根节点时,只需在要继承 attribute 的节点上绑定 v-bind="$attrs" 即可
*/
export default {
  inheritAttrs: false
}
</script>
<script setup lang="ts">
import VueDatePicker from '@vuepic/vue-datepicker'
import '@vuepic/vue-datepicker/dist/main.css'
import { computed } from 'vue'
interface Props {
  width?: number // 日期选择器宽度
  mode?: 'time'|'date'|'week'|'month'|'year' // 选择器模式,可选:时间time,日期date,周week,月month,年year
  // format?: string | (params: Date | Date[]) => string // 日期展示格式,(y: 年, M: 月, d: 天, H: 时, m: 分, s: 秒)
  showTime?: boolean // 是否增加时间选择
  showToday?: boolean // 是否展示”今天“按钮
  // multiCalendars?: boolean // 范围选择器是否使用双日期面板
  // flow?: any[] // 定义选择顺序 ("calendar" | "time" | "month" | "year" | "minutes" | "hours" | "seconds")[]
  // dark?: boolean // 样式主题是否使用黑色
  modelType?: 'timestamp'|'format', // v-model 值类型,可选时间戳(timestamp)、字符串(format),mode为week和year时,该配置不生效
}
const props = withDefaults(defineProps<Props>(), {
  width: 180,
  mode: 'date',
  /* format default
    Single picker: 'MM/dd/yyyy HH:mm'
    Range picker: 'MM/dd/yyyy HH:mm - MM/dd/yyyy HH:mm'
    Month picker: 'MM/yyyy'
    Time picker: 'HH:mm'
    Time picker range: 'HH:mm - HH:mm'
  */
  showTime: false,
  showToday: false,
  // multiCalendars: false,
  // flow: () => [],
  // dark: false,
  modelType: 'format'
})
const time = computed(() => {
  return props.mode === 'time'
})
const week = computed(() => {
  return props.mode === 'week'
})
const month = computed(() => {
  return props.mode === 'month'
})
const year = computed(() => {
  return props.mode === 'year'
})
// const format = (date: Date) => {
//   const day = date.getDate()
//   const month = date.getMonth() + 1
//   const year = date.getFullYear()
//   return `${year}-${month}-${day}`
// }
</script>
<template>
  <div class="m-datepicker" :style="`width: ${width}px;`">
    <VueDatePicker
      locale="zh-CN"
      :month-change-on-scroll="false"
      :enable-time-picker="showTime"
      :time-picker="time"
      :week-picker="week"
      :month-picker="month"
      :year-picker="year"
      now-button-label="今天"
      :show-now-button="showToday"
      auto-apply
      text-input
      :model-type="modelType"
      :day-names="['一', '二', '三', '四', '五', '六', '七']"
      v-bind="$attrs">
    </VueDatePicker>
  </div>
</template>
<style lang="less" scoped>
.m-datepicker {
  display: inline-block;
}
.dp__theme_dark { // dark theme
  --dp-background-color: #212121;
  --dp-text-color: #ffffff;
  --dp-hover-color: #484848;
  --dp-hover-text-color: #ffffff;
  --dp-hover-icon-color: #959595;
  --dp-primary-color: #005cb2;
  --dp-primary-text-color: #ffffff;
  --dp-secondary-color: #a9a9a9;
  --dp-border-color: #2d2d2d;
  --dp-menu-border-color: #2d2d2d;
  --dp-border-color-hover: #aaaeb7;
  --dp-disabled-color: #737373;
  --dp-scroll-bar-background: #212121;
  --dp-scroll-bar-color: #484848;
  --dp-success-color: #00701a;
  --dp-success-color-disabled: #428f59;
  --dp-icon-color: #959595;
  --dp-danger-color: #e53935;
  --dp-highlight-color: rgba(0, 92, 178, .2);
}
.dp__theme_light { // light theme
  --dp-background-color: #ffffff;
  --dp-text-color: #212121;
  --dp-hover-color: #f3f3f3;
  --dp-hover-text-color: #212121;
  --dp-hover-icon-color: #959595;
  --dp-primary-color: #1976d2;
  --dp-primary-text-color: #f8f5f5;
  --dp-secondary-color: #c0c4cc;
  --dp-border-color: #ddd;
  --dp-menu-border-color: #ddd;
  --dp-border-color-hover: #aaaeb7;
  --dp-disabled-color: #f6f6f6;
  --dp-scroll-bar-background: #f3f3f3;
  --dp-scroll-bar-color: #959595;
  --dp-success-color: #76d275;
  --dp-success-color-disabled: #a3d9b1;
  --dp-icon-color: #959595;
  --dp-danger-color: #ff6f60;
  --dp-highlight-color: rgba(25, 118, 210, .1);
}
</style>

②在要使用的页面引入:

<script setup lang="ts">
import DatePicker from './DatePicker.vue'
import pkg from '/package.json'
import { ref, watchEffect } from 'vue'
import { format, endOfMonth, endOfYear, startOfMonth, startOfYear, subMonths, addDays, startOfWeek, endOfWeek, addHours, addMinutes, addSeconds } from 'date-fns'

const dateValue = ref(format(new Date(), 'yyyy-MM-dd'))
const dateTimeValue = ref(format(new Date(), 'yyyy-MM-dd HH:mm:ss'))
const rangeValue = ref<string[]>([format(new Date(), 'yyyy-MM-dd'), format(addDays(new Date(), 1), 'yyyy-MM-dd')])
console.log(addHours(Date.now(), 1))
console.log('rangeValue', rangeValue.value)

const timeRangeValue = ref([
  {
    hours: new Date().getHours(),
    minutes: new Date().getMinutes(),
    seconds: new Date().getSeconds()
  },
  {
    hours: addHours(Date.now(), 1).getHours(),
    minutes: addMinutes(Date.now(), 10).getMinutes(),
    seconds: addSeconds(Date.now(), 30).getSeconds()
  }
])
const presetDates = ref([
  { label: 'Today', value: [new Date(), new Date()] },
  { label: 'This month', value: [startOfMonth(new Date()), endOfMonth(new Date())] },
  {
    label: 'Last month',
    value: [startOfMonth(subMonths(new Date(), 1)), endOfMonth(subMonths(new Date(), 1))],
  },
  { label: 'This year', value: [startOfYear(new Date()).getTime(), endOfYear(new Date()).getTime()] }
])
const timeValue = ref({
  hours: new Date().getHours(),
  minutes: new Date().getMinutes()
})
const secondsValue = ref({
  hours: new Date().getHours(),
  minutes: new Date().getMinutes(),
  seconds: new Date().getSeconds()
})
const weekValue = ref([startOfWeek(new Date()), endOfWeek(new Date())])
const monthValue = ref({
  year: new Date().getFullYear(),
  month: new Date().getMonth()
})
const yearValue = ref(new Date().getFullYear())

watchEffect(() => {
  console.log('dateValue:', dateValue.value)
})
watchEffect(() => {
  console.log('dateTimeValue:', dateTimeValue.value)
})
watchEffect(() => {
  console.log('rangeValue:', rangeValue.value)
})
watchEffect(() => {
  console.log('timeRangeValue:', timeRangeValue.value)
})
watchEffect(() => {
  console.log('timeValue:', timeValue.value)
})
watchEffect(() => {
  console.log('secondsValue:', secondsValue.value)
})
watchEffect(() => {
  console.log('weekValue:', weekValue.value)
})
watchEffect(() => {
  console.log('monthValue:', monthValue.value)
})
watchEffect(() => {
  console.log('yearValue:', yearValue.value)
})
</script>
<template>
  <div>
    <h1>DatePicker 参考文档</h1>
    <ul class="m-list">
      <li>
        <a class="u-file" href="https://vue3datepicker.com/" target="_blank">Vue Datepicker</a>
      </li>
      <li>
        <a class="u-file" href="https://vue3datepicker.com/installation/" target="_blank">Vue Datepicker Documents</a>
      </li>
    </ul>
    <Space align="top" class="mt30" :size="6">
      <h1>DatePicker</h1>
      <Tag color="volcano">{
   { pkg.dependencies['@vuepic/vue-datepicker'] }}</Tag>
    </Space>
    <h2 class="mt30 mb10">基本使用</h2>
    <DatePicker
      placeholder="请选择日期"
      v-model="dateValue"
      show-today
      format="yyyy-MM-dd" />
    <h2 class="mt30 mb10">禁用过去</h2>
    <DatePicker
      placeholder="请选择日期"
      v-model="dateValue"
      :min-date="new Date()"
      format="yyyy-MM-dd" />
    <h2 class="mt30 mb10">禁用未来</h2>
    <DatePicker
      placeholder="请选择日期"
      v-model="dateValue"
      :max-date="new Date()"
      format="yyyy-MM-dd" />
    <h2 class="mt30 mb10">日期时间选择器</h2>
    <DatePicker
      placeholder="请选择日期时间"
      v-model="dateTimeValue"
      format="yyyy-MM-dd HH:mm:ss"
      :width="240"
      show-time
      enable-seconds />
    <h2 class="mt30 mb10">日期范围选择器</h2>
    <DatePicker
      placeholder="请选择日期范围"
      v-model="rangeValue"
      range
      :preset-dates="presetDates"
      format="yyyy-MM-dd"
      :width="280" />
    <h2 class="mt30 mb10">日期范围选择器,双日期面板</h2>
    <DatePicker
      placeholder="请选择日期范围"
      v-model="rangeValue"
      mode="range"
      format="yyyy-MM-dd"
      :width="280"
      range
      multi-calendars />
    <h2 class="mt30 mb10">预设范围</h2>
    <h3 class="mb10">预设常用的日期范围以提高用户体验</h3>
    <DatePicker
      placeholder="请选择日期范围"
      mode="range"
      format="yyyy-MM-dd"
      :width="280"
      range
      :preset-dates="presetDates"
      multi-calendars
      v-model="rangeValue" />
    <h2 class="mt30 mb10">时分选择器</h2>
    <DatePicker
      placeholder="请选择时间"
      v-model="timeValue"
      mode="time"
      show-time
      mode-height="120"
      format="HH:mm"
      :width="120" />
    <h2 class="mt30 mb10">时分秒选择器</h2>
    <DatePicker
      placeholder="请选择时间"
      v-model="secondsValue"
      mode="time"
      show-time
      enable-seconds
      mode-height="120"
      format="HH:mm:ss"
      :width="150" />
    <h2 class="mt30 mb10">时分秒范围选择器</h2>
    <DatePicker
      placeholder="请选择时间"
      v-model="timeRangeValue"
      mode="time"
      show-time
      range
      enable-seconds
      mode-height="120"
      format="HH:mm:ss"
      :width="240" />
    <h2 class="mt30 mb10">周选择器</h2>
    <DatePicker
      placeholder="请选择周"
      v-model="weekValue"
      mode="week"
      format="yyyy-MM-dd"
      :width="280" />
    <h2 class="mt30 mb10">月选择器</h2>
    <DatePicker
      placeholder="请选择月"
      v-model="monthValue"
      mode="month"
      format="yyyy-MM"
      :width="150" />
    <h2 class="mt30 mb10">年选择器</h2>
    <DatePicker
      placeholder="请选择年"
      v-model="yearValue"
      mode="year"
      format="yyyy"
      :width="120" />
  </div>
</template>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Dandrose/article/details/129954665

智能推荐

【爬虫】Xpath和CSS信息提取的方法异同点_xpath 获取css-程序员宅基地

文章浏览阅读2.3k次,点赞2次,收藏8次。Xpath和CSS信息提取的方法异同点_xpath 获取css

剑指 Offer(专项突击版)- 剑指 Offer II 052. 展平二叉搜索树(20220729)-程序员宅基地

文章浏览阅读95次。剑指 Offer II 052. 展平二叉搜索树

Xilinx AXI Interconnect_axi interconnect不同位宽-程序员宅基地

文章浏览阅读1.2w次,点赞12次,收藏118次。目录0、绪论1、AXI Crossbar1.1、几种可以选择的Crossbar 互联结构1.1.1、Crossbar mode (Performance Optimized)1.1.2、Shared Access mode (Area optimized)2、AXI Data Width Converter3、AXI Clock Converter4、AXI Pr..._axi interconnect不同位宽

Linux部署Django_Vue_linux 安装django vue3-程序员宅基地

文章浏览阅读340次。linux宝塔_linux 安装django vue3

win7访问smb文件服务器,win7系统配置smb服务器-程序员宅基地

文章浏览阅读1.3k次。win7系统配置smb服务器 内容精选换一换首次开机时,缺省进入遥控器配置向导界面。遥控器操作界面选择“系统设置 > 配置向导”,进入“配置向导”界面。网线连接:当终端有插入网线时,进入“LAN”界面(仅支持IPv4格式),如图3所示。请联系管理员获取网络配置方式,配置方式请参见表1。配置方式配置项操作自动获取终端通过DHCP(Dynamic Host Configuration操作系统镜像..._win7 设置smb访问方式

win10总显示打印机未连接服务器,win10系统打印机共享提示连接失败的解决方法...-程序员宅基地

文章浏览阅读1w次。win10系统打印机共享提示连接失败的解决方法?我们在操作win10系统电脑的时候,常常会遇到win10系统打印机共享提示连接失败的问题。那么出现win10系统打印机共享提示连接失败的问题该怎么解决呢?很多对电脑不太熟悉的小伙伴不知道win10系统打印机共享提示连接失败到底该如何解决?其实只需要通常打印机安装在一台电脑主机上,然后由别的电脑通过局域网共享这台打印机,首先要知道安装打印机的电脑主机的..._win10连接win10共享打印机一直打印机服务未开启

随便推点

Extjs4.2 window加载HTML,父子页面html传参_extjs中打开网页怎么传参-程序员宅基地

文章浏览阅读482次。Extjs的窗口是可以加载自己的HTML的,但这样两个页面就相当独立了,传参是个问题 ,网上也没有很好的解答清楚,猫猫今天就说清楚这个模式的传参要点。_extjs中打开网页怎么传参

计算机网络复习——Ch3点到点数据链路层_hdlc go-back-n-程序员宅基地

文章浏览阅读1.2k次。Ch3点到点数据链路层知识点1. 点到点数据链路层要解决的主要问题2. 常见的帧管理(帧定界)方法3. CRC的计算4. 流量控制的基本原理5. 常见错误及其处理机制6. 滑动窗口的概念、形式及工作原理7. ARQ(Automatic Repeat reQuest)协议工作原理:8. 连续ARQ(Go-back-N ARQ)工作原理(特别注意累计确认):9. 选择重传ARQ工作原理10. 了解(高..._hdlc go-back-n

oracle四大索引类型,各种Oracle索引类型介绍-程序员宅基地

文章浏览阅读2.6k次。逻辑上:Single column 单行索引Concatenated 多行索引Unique 唯一索引NonUnique 非唯一索引Function-based函数索引Domain 域索引物理上:Partitioned 分区索引NonPartitioned 非分区索引B-tree:Normal 正常型B树Rever Key 反转型B树Bitmap 位图索引索引结构:B-tree:适合与大量的增、删、..._oracle索引有哪几种类型

CountDownLatch闭锁_countdownlatch illegate-程序员宅基地

文章浏览阅读176次。11_countdownlatch illegate

Android初步进阶之MVVM框架使用_android mvvm的进阶用法-程序员宅基地

文章浏览阅读199次。MVVM模式引入双向绑定。首先,看一看MVVM的模式的图示。![在这里插入图片描述](https://img-blog.csdnimg.cn/20201108124734892.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjUxNDE2Mg==,size_16,color_FFFFFF,t_70#pic_center_android mvvm的进阶用法

推荐文章

热门文章

相关标签