打开antd vue官网我们会发现,日期选择框控件只有DatePicker、MonthPicker、RangePicker、WeekPicker,唯独缺少了YearPicker,但是我们在项目中会用到只选择年份的控件,那么这时候就需要我们在此基础上自己进行组件的封装了。

  1. 通过官网我们会看到,它的属性有mode以及format
    在这里插入图片描述
    在这里插入图片描述
    看到这两个属性,也许我们会很开心,觉得这就够了,然后就设置一下:
format="YYYY"
mode="year"

迫不及待的想看一下效果:

在这里插入图片描述

此时我们会发现,样式是出来了,但是是无法被选中的,而且折叠面板也是无法收起的。

  1. 那么就需要从open属性以及openChangepanelChange事件入手了

在这里插入图片描述
① 属性及事件如下:

:open="open"
@openChange="openChange"
@panelChange="panelChange"

② 弹出和关闭日历的回调

openChange(status) {
 if (status) {
    this.open = true;
  } else {
    this.open = false;
  }
},

③ 日期面板变化时的回调

panelChange(value) {
   // 获取到的时间赋值给widgetVal
   this.widgetVal = String(value.year());
   this.open = false;
 },
  1. 完整代码如下:
<template>
  <div>
    <ADatePicker
      v-model="year"
      @change="onChange"
      placeholder="请选择"
      format="YYYY"
      mode="year"
      :open="open"
      @openChange="openChange"
      @panelChange="panelChange"
      :showTime="showTime"
      class="drw-container"
      :disabledDate="disabledDate"
      :style="{width: field.width || 'auto'}"
      :getCalendarContainer="getPopupContainer()"
      :allowClear="field.allowClear === undefined ? false : field.allowClear"
    />
  </div>
</template>
<script>
import moment from 'moment'
import {dtUtil} from "jscom/utils/sysutil"
import BaseWidget from './BaseWidget'

/**
 * widgetVal 格式默认为 YYYY-mm-dd HH:MM:SS,如果设置 field.useTimestamp 那么就是 时间戳毫秒格式
 */
export default {
  name: 'YeartimeWidget',
  extends: BaseWidget,
  supportReadonly: true,
  inject: ['popupContainer'],
  data() {
    let mode = ''
    let showTime = false
    let dateName = ''
    let format = ''
    return {
      open: false,
      year: null,
      mode,
      showTime,
      dateName,
      format,
    }
  },
  watch: {
    widgetVal(val) {
      this.updateTmVal()
    },
  },
  mounted() {
    this.updateTmVal()
  },
  methods: {
    moment,
    /**
     * 弹出日历和关闭日历的回调
     */
    openChange(status) {
      if (status) {
        this.open = true;
      } else {
        this.open = false;
      }
    },
    /**
     * 日期面板变化时的回调
     */
    panelChange(value) {
      this.widgetVal = String(value.year());
      this.open = false;
    },
    /**
     * 更新时间值
     */
    updateTmVal() {
      if (!this.widgetVal) return
      if (this.field.useTimestamp) {
        this.year = moment(this.widgetVal)
      } else {  // str format
        this.year = moment(this.widgetVal)
      }
    },
    /**
     * 支持数据类型声明
     * @returns {string[]}
     */
    supportTypes() {
      return ['datetime', 'date', 'month', 'year']
    },
    /**
     * 控件修改触发
     */
    onChange(date, dateString) {
      if (this.field.useTimestamp) {
        this.widgetVal = date.valueOf()  // 时间戳 毫秒
      } else {
        this.widgetVal = dateString
      }
    },
    /**
     * 占位符文字
     * @returns {*|string}
     */
    placeholder() {
      return this.field.placeholder || `请选择${this.dateName}`
    },
    /**
     * 禁止日期选择逻辑
     */
    disabledDate (current) {
      if (this.field.startDate) {
        return current <= this.field.startDate
      }
      if (this.field.endDate) {
        return current >= this.field.endDate
      }
      // 屏蔽过去的日期
      if (this.field.disablePastDate) {
        return current && current < moment().startOf('day')
      }
      return false
    },
    /**
     * 获取弹出框容器
     */
    getPopupContainer () {
      if (this.popupContainer) {
        return () => {
          return this.popupContainer()
        }
      } else {
        return () => document.body
      }
    }
  },
}
</script>

<style lang="less">
.drw-container {
  max-width: 398px;
  min-width: 200px;
}
</style>

此时再看效果:

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐