vue3+element-plus el-date-picker日期组件再次封装(DatePicker与DateTimePicker合并根据type值来显示并自定义常规快捷方式)

最新推荐文章于 2024-09-05 09:34:10 发布
最新推荐文章于 2024-09-05 09:34:10 发布 阅读量4.5k 文章介绍了TDatePicker组件,它是基于ElementUI的DatePicker和DateTimePicker组件的二次封装。支持多种日期和时间类型选择,包括周、月、年、日期范围等,并提供了快捷选项配置。用户可以通过type属性来设定日期选择类型,同时支持自定义快捷方式和事件监听。源码展示了如何处理不同类型的日期格式和快捷选项,以及如何响应v-model的变化。 摘要由CSDN通过智能技术生成

1、简介:基于 ElementUI DatePicker DateTimePicker 组件的二次封装,取决于 type 值

代码示例:

<t-date-picker v-model="date" />

2、t-date-picker(Attributes)继承 DatePicker DateTimePicker 的 Attributes

参数说明类型默认值
v-model绑定值[String, Date, Array]-
plusTime日期范围是否显示 00:00:00 23:59:59 时分秒Booleanfalse
type时间类型(继承 element DatePicker DateTimePicker)Stringdate
shortcuts设置快捷选项,需要传入数组对象Array<{ text: string, value: Date & Function }>-
isPickerOptions是否开启自带快捷方式Booleanfalse

3、type 类型如下:

week 周;month 月;year 年;dates 多个日期;months 多个月;years 多个年;daterange 日期范围;monthrange 月份范围;datetime 日期和时间点;datetimerange 日期和时间点范围

4、events

事件名说明返回值
change用户确认选定的值时触发组件绑定值。格式与绑定值一致,可受 value-format 控制

Slots

事件名说明
default自定义内容
range-separator自定义范围分割符内容
<template>
  <div class="t-date-picker">
    <el-date-picker
      :type="type"
      v-model="time"
      :shortcuts="state.dateOptions"
      @change="dateChange"
      v-bind="attrsBind"
      <template v-for="(index, name) in slots" v-slot:[name]="data">
        <slot :name="name" v-bind="data"></slot>
      </template>
    </el-date-picker>
  </div>
</template>
<script lang="ts">
export default {
  name: 'TDatePicker',
</script>
<script setup lang="ts">
import { computed, useAttrs, useSlots, watch, reactive } from 'vue'
const props = defineProps({
  value: {
    type: [String, Date, Array],
  // 日期范围是否显示00:00:00 23:59:59时分秒
  plusTime: {
    type: Boolean,
    default: false,
  // 时间类型
   * week周;month月;year年;dates多个日期;months多个月;years多个年;daterange日期范围;monthrange月份范围
   * datetime日期和时间点;datetimerange日期和时间点范围
  type: {
    type: String,
    default: 'date',
  // 快捷配置
  shortcuts: {
    type: Array,
  // 是否开启快捷方式
  isPickerOptions: {
    type: Boolean,
    default: false,
// 抛出事件
const emits = defineEmits(['update:modelValue', 'change'])
const $attrs: any = useAttrs()
const slots = useSlots()
// vue3 v-model简写
let time: any = computed({
  get() {
    return props.value
  set(val) {
    // console.log(777, val)
    emits('update:modelValue', val)
const attrsBind = computed(() => {
  const { type } = props
  let attrs = {}
  switch (type) {
    case 'date':
    case 'dates':
      attrs['value-format'] = 'YYYY-MM-DD'
      attrs['placeholder'] = '请选择日期'
      break
    case 'week':
      // attrs['value-format'] = 'YYYY - ww'
      attrs['format'] = 'YYYY 第 ww 周'
      attrs['placeholder'] = '请选择周'
      break
    case 'month':
    case 'months':
      attrs['value-format'] = 'YYYY-MM'
      attrs['format'] = 'YYYY-MM'
      attrs['placeholder'] = '请选择月'
      break
    case 'year':
    case 'years':
      attrs['value-format'] = 'YYYY'
      attrs['format'] = 'YYYY'
      attrs['placeholder'] = '请选择年'
      break
     * 日期范围
    case 'daterange':
      attrs['value-format'] = 'YYYY-MM-DD'
      attrs['range-separator'] = '~'
      attrs['start-placeholder'] = '请选择开始日期'
      attrs['end-placeholder'] = '请选择结束日期'
      break
    case 'monthrange':
      attrs['value-format'] = 'YYYY-MM'
      attrs['range-separator'] = '~'
      attrs['start-placeholder'] = '请选择开始月份'
      attrs['end-placeholder'] = '请选择结束月份'
      break
     * 日期和时间点
    case 'datetime':
      attrs['format'] = 'YYYY-MM-DD HH:mm:ss'
      attrs['value-format'] = 'YYYY-MM-DD HH:mm:ss'
      attrs['placeholder'] = '请选择日期时间'
      break
    case 'datetimerange':
      attrs['format'] = 'YYYY-MM-DD HH:mm:ss'
      attrs['value-format'] = 'YYYY-MM-DD HH:mm:ss'
      attrs['range-separator'] = '~'
      attrs['start-placeholder'] = '请选择开始日期'
      attrs['end-placeholder'] = '请选择结束日期'
      break
  return {
    ...attrs,
    ...$attrs,
const state = reactive({
  dateOptions: props.shortcuts,
// 获取快捷配置
const getShortcuts = (type: any) => {
  let shortcuts: any = []
  switch (type) {
    case 'date':
      shortcuts = [
          text: '今天',
          value: new Date(),
          text: '昨天',
          value: () => {
            const date = new Date()
            date.setTime(date.getTime() - 3600 * 1000 * 24)
            return date
          text: '一周前',
          value: () => {
            const date = new Date()
            date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
            return date
      break
    case 'daterange':
      shortcuts = [
          text: '最近一周',
          value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            return [start, end]
          text: '最近一个月',
          value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            return [start, end]
          text: '最近三个月',
          value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            return [start, end]
      break
    case 'monthrange':
      shortcuts = [
          text: '本月',
          value: [new Date(), new Date()],
          text: '今年至今',
          value: () => {
            const end = new Date()
            const start = new Date(new Date().getFullYear(), 0)
            return [start, end]
          text: '最近六个月',
          value: () => {
            const end = new Date()
            const start = new Date()
            start.setMonth(start.getMonth() - 6)
            return [start, end]
      break
    case 'datetime':
      shortcuts = [
          text: '今天',
          value: new Date(),
          text: '昨天',
          value: () => {
            const date = new Date()
            date.setTime(date.getTime() - 3600 * 1000 * 24)
            return date
          text: '一周前',
          value: () => {
            const date = new Date()
            date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
            return date
      break
    case 'datetimerange':
      shortcuts = [
          text: '最近一周',
          value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            return [start, end]
          text: '最近一个月',
          value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            return [start, end]
          text: '最近三个月',
          value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            return [start, end]
      break
  return shortcuts
const dateChange = (val: any[]) => {
  const { type } = props
  if (type === 'daterange' && val) {
    let startTime = val[0]
    let endTime = val[1]
    if (props.plusTime) {
      startTime = startTime + ' 00:00:00'
      endTime = endTime + ' 23:59:59'
    time.value = [startTime, endTime]
    emits('change', [startTime, endTime])
  } else {
    emits('change', val)
if (props.isPickerOptions) {
  state.dateOptions = getShortcuts(props.type)
watch(
  () => props.value,
  (val) => {
    // console.log(111, val)
    time.value = val
  { deep: true }
watch(
  () => props.shortcuts,
  (val) => {
    if (props.isPickerOptions) {
      let shortcuts = getShortcuts(props.type)
      state.dateOptions = shortcuts
    } else {
      state.dateOptions = val
  { deep: true }
// 暴露方法出去
defineExpose({ state })
</script>

4、组件地址

gitHub组件地址

gitee码云组件地址

5、相关文章

基于ElementUi&AntdUi再次封装基础组件文档

vue3+ts基于Element-plus再次封装基础组件文档

在后端实体类中的日期格式: @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") private Date endtime; 前端的控件: <el-date-picker v-model="dataForm.end 1. 下载需要的图标素材,可以是svg、png、jpg等格式的图片。 2. 将下载的图标素材放置到项目中的某个目录下,比如`src/icons/svg`目录。 3. 在`main.js`中引入`@element-plus/icons`,并注册自定义图标。 ```javascript import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' import { register } from '@element-plus/icons' import { App as AppIcon } from './icons/svg/app.svg' register({ 'app': AppIcon createApp(App).use(ElementPlus).mount('#app') 4. 在需要使用自定义图标的地方,使用`el-icon`组件,并传入注册的图标名称。 ```html <template> <el-icon name="app"></el-icon> </template> 以上就是vite+vue3+element-plus图标自定义的实现方式。 vue项目 解决el-table自适应高度,vue页面不显示多条滚动条,超出的部分让el-table内部出现滚动条(推荐使用第二种解决方案;TAdaptivePage 组件新增左右分栏布局) 20241