用 element ui 实现季度选择器

这篇具有很好参考价值的文章主要介绍了用 element ui 实现季度选择器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

由于在数据项目中经常以各种时间条件查询数据,所以时间选择器(DatePicker)组件是很常用的组件。但是在我使用的 Element UI 中,缺少了季度选择器的功能。

简易实现

一开始我根据时间范围使用 select 去遍历,如 2024-Q1、2023-Q4、2023-Q3 如此类推。

用 element ui 实现季度选择器,ui,javascript,开发语言

element 并无季度选择器

其实也算是快速解决了 element ui 无法选择季度的问题。但总感觉特别的 low,后来有时间了就去隔壁 ant design 看了看。

用 element ui 实现季度选择器,ui,javascript,开发语言

发现在新版的 ant design 都支持季度和季度范围选择器了……

查了查新的 element plus 也只是只支持了 'year' | 'years' |'month' | 'date' | 'dates' | 'datetime' | 'week' | 'datetimerange' | 'daterange' | 'monthrange' 这些个类型。

工具不给力,又不想用其他库的情况下只能手搓了。

手搓季度选择器

季度面板

参考 ant design 做了一个类似的面板。

用 element ui 实现季度选择器,ui,javascript,开发语言

<template>
  <div class="quarter-panel">
    <div class="quarter-panel-header">
      <i
        class="quarter-panel-header-icon el-icon-arrow-left"
        @click="currentYear--"
      />
      <div class="quarter-panel-header-title">{{ currentYear }} 年</div>
      <i
        class="quarter-panel-header-icon el-icon-arrow-right"
        @click="currentYear++"
      />
    </div>
    <div class="quarter-panel-content">
      <div
        v-for="option in quarterOptions"
        class="quarter-panel-item-btn"
        :class="getComputedClass(option.value)"
        :key="option.value"
        @click="emitClick(option.value)"
      >
        {{ option.label }}
      </div>
    </div>
  </div>
</template>

<script>
import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'

dayjs.extend(customParseFormat)

export default {
  name: 'QuarterPanel',
  props: {
    value: String,
    dice: Number,
    min: String,
    max: String,
    todayDisabled: Boolean,
    featureDisabled: Boolean,
  },
  data() {
    return {
      currentYear: 2023,
    }
  },
  computed: {
    day() {
      if (this.value) {
        return dayjs(this.value, 'YYYY-MM-DD')
      }
      return dayjs()
    },
    computedDate() {
      return this.day.startOf('quarter').format('YYYY-MM-DD')
    },
    quarterOptions() {
      return [
        { label: 'Q1', value: `${this.currentYear}-01-01` },
        { label: 'Q2', value: `${this.currentYear}-04-01` },
        { label: 'Q3', value: `${this.currentYear}-07-01` },
        { label: 'Q4', value: `${this.currentYear}-10-01` },
      ]
    },
  },
  mounted() {
    this.currentYear = dayjs().year()
  },
  methods: {
    getDisabled(value) {
      let isFeature = false

      if (this.todayDisabled) {
        isFeature = dayjs()
          .subtract(1, 'day')
          .startOf('quarter')
          .isBefore(dayjs(value))
      } else if (this.featureDisabled) {
        isFeature = dayjs().startOf('quarter').isBefore(dayjs(value))
      }

      const isMin = this.min
        ? dayjs(this.min, 'YYYY-MM-DD')
            .startOf('quarter')
            .isAfter(dayjs(value, 'YYYY-MM-DD'))
        : false

      const isMax = this.max
        ? dayjs(this.max, 'YYYY-MM-DD')
            .startOf('quarter')
            .isBefore(dayjs(value, 'YYYY-MM-DD'))
        : false

      return isFeature || isMin || isMax
    },
    getComputedClass(value) {
      if (this.computedDate === value) {
        return 'quarter-panel-item-btn-active'
      }
      if (this.getDisabled(value)) {
        return 'quarter-panel-item-btn-disabled'
      }
      return ''
    },
    emitClick(value) {
      if (this.getDisabled(value)) {
        return
      }
      this.$emit('input', value)
    },
  },
  watch: {
    dice() {
      this.currentYear = this.day.year()
    },
  },
}
</script>

<style lang="scss" scoped>
$--gw-primary-color: #f6674f;

.quarter-panel {
  width: 200px;
  color: #303133;

  .quarter-panel-header {
    height: 30px;
    padding: 12px;
    display: flex;
    align-items: center;

    .quarter-panel-header-icon {
      font-size: 12;
      margin: 5px;
      cursor: pointer;

      &:hover {
        color: $--gw-primary-color;
      }
    }

    .quarter-panel-header-title {
      flex: 1;
      text-align: center;
      font-size: 16;
    }
  }

  .quarter-panel-content {
    display: flex;
    align-items: center;

    .quarter-panel-item-btn {
      flex: 1;
      font-size: 14;
      height: 30px;
      line-height: 30px;
      text-align: center;
      cursor: pointer;
      border: solid 1px transparent;
      border-radius: 5px;

      &:hover {
        color: $--gw-primary-color;
        border: solid 1px $--gw-primary-color;
      }
    }

    .quarter-panel-item-btn-active {
      background: $--gw-primary-color;
      color: #ffffff;

      &:hover {
        color: #ffffff;
      }
    }

    .quarter-panel-item-btn-disabled {
      color: #909399;
      background: #f2f6fc;
      cursor: not-allowed;

      &:hover {
        color: #909399;
        background: #f2f6fc;
      }
    }
  }
}
</style>

季度选择器

将面板放到 el-popover 中实现类似 DatePicker 的效果。并且提供了像清空数据、最大值、最小值等常用功能。

用 element ui 实现季度选择器,ui,javascript,开发语言

<template>
  <div class="quarter-picker" :class="{ 'quarter-picker-disabled': disabled }">
    <div class="quarter-picker-date-button">
      <i class="iconfont icon-date-select-icon quarter-picker-time-icon" />
      <el-popover
        placement="bottom-start"
        width="200"
        trigger="click"
        ref="datePopover"
        :disabled="disabled"
        @show="initPopover"
      >
        <div
          class="quarter-picker-date-button-item quarter-picker-date-button-item-long"
          slot="reference"
        >
          <span v-if="form.date" class="button-item-span">
            {{ dateQuarterStr }}
          </span>
          <span v-else class="button-item-span">选择时间</span>
          <div class="bottom-line" />
        </div>
        <quarterPanel
          v-model="form.date"
          :dice="dice"
          :min="min"
          :max="max"
          :featureDisabled="featureDisabled"
          :todayDisabled="todayDisabled"
          @input="emitDateChange()"
        />
      </el-popover>
      <i
        v-show="form.date && clearable"
        class="el-icon-close quarter-picker-clear-icon"
        @click.stop="clearCurrentDate"
      />
    </div>
  </div>
</template>

<script>
import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
import quarterOfYear from 'dayjs/plugin/quarterOfYear'

import quarterPanel from './quarterPanel.vue'

dayjs.extend(customParseFormat)
dayjs.extend(quarterOfYear)

/**
 * date 日期
 */
export default {
  name: 'QuarterPicker',
  components: {
    quarterPanel,
  },
  props: {
    date: String,
    min: String,
    max: String,
    featureDisabled: Boolean,
    todayDisabled: Boolean,
    disabled: Boolean,
    clearable: Boolean,
  },
  data() {
    return {
      form: {
        date: '',
      },
      dice: 0,
    }
  },
  mounted() {
    this.syncData()
  },
  computed: {
    dateQuarterStr() {
      if (!this.form.date) return '选择季'

      const dj = dayjs(this.form.date).startOf('quarter')
      return `${dj.year()}-Q${dj.quarter()}`
    },
  },
  methods: {
    initPopover() {
      this.dice++
    },
    syncData() {
      this.form.date = this.date
    },
    clearCurrentDate() {
      if (this.disabled) return
      this.form.date = ''

      this.emitDateChange()
    },
    emitDateChange() {
      this.$emit('change', this.form)

      this.closePopovers()
    },
    closePopovers() {
      this.$refs.datePopover.doClose()
    },
  },
  watch: {
    date() {
      if (this.form.date !== this.date) {
        this.syncData()
      }
    },
  },
}
</script>

<style scoped lang="scss">
$--gw-primary-color: #f6674f;

.quarter-picker {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;

  .quarter-picker-date-button {
    display: flex;
    position: relative;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    user-select: none;
    margin-left: 5px;
    width: 250px;
    padding-left: 10px;
    height: 28px;
    background: #ffffff;
    border: 1px solid #dcdfe6;
    font-size: 14px;
    font-family: Microsoft YaHei;
    font-weight: 400;
    color: #282c32;
    border-radius: 4px;

    .quarter-picker-time-icon {
      position: absolute;
      left: 12px;
    }

    .quarter-picker-date-button-item {
      position: relative;
      height: 28px;
      line-height: 28px;
      text-align: center;
      width: 70px;
      cursor: pointer;

      .bottom-line {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 2px;
        border-radius: 1px;
        background: transparent;
      }

      &:hover {
        .bottom-line {
          background: $--gw-primary-color;
        }
      }
    }

    .quarter-picker-date-button-item-long {
      width: 200px;

      .button-item-span {
        display: inline-block;
        width: 90px;
        text-align: center;
      }

      .button-item-span-active {
        color: $--gw-primary-color;
      }
    }

    .quarter-picker-clear-icon {
      position: absolute;
      right: 12px;
      font-size: 14;
      cursor: pointer;

      &:hover {
        color: $--gw-primary-color;
      }
    }
  }
}

.quarter-picker-disabled {
  .quarter-picker-date-button {
    color: #c0c4cc;
    background-color: #f2f6fc;

    .quarter-picker-date-button-item {
      cursor: not-allowed;
    }
  }

  .quarter-picker-date-button-item {
    &:hover {
      .bottom-line {
        background: transparent !important;
      }
    }
  }

  .quarter-picker-clear-icon {
    cursor: not-allowed !important;

    &:hover {
      color: #c0c4cc !important;
    }
  }
}
</style>

组件的使用

最后就是组件的使用了:

  <QuarterPicker
    type="quarter"
    :date="quarter.date"
    :min="minDate"
    :max="maxDate"
    :featureDisabled="options.featureDisabled"
    :todayDisabled="options.todayDisabled"
    :disabled="options.disabled"
    :clearable="options.clearable"
    @change="handleQuarterPickerChange"
  />
handleQuarterPickerChange({ date }) {
  this.quarter.date = date

  this.$message({
    message: '触发查询请求',
    type: 'success',
  })
},

最后

另外,季度范围选择器也可以用类似的思路来实现。以上就是个人解决季度选择器的方式。希望能对有类似需求的同学一些帮助。文章来源地址https://www.toymoban.com/news/detail-860402.html

到了这里,关于用 element ui 实现季度选择器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于vue+element ui实现下拉表格选择组件

    根据https://lolicode.gitee.io/scui-doc/demo/#/dashboard里的组件修改

    2024年02月16日
    浏览(56)
  • WPF实现Element UI风格的日期时间选择器

    业务开发过程中遇到一个日期范围选择的需求,和Element UI的DateTimePicker组件比较类似,由两个日历控件组成,联动选择起始时间和结束时间。 WPF中提供了一个 DatePicker 的控件,主要由 DatePickerTextBox 、 Button 和一个 Calendar 组成,其中 Calendar 是后台代码动态添加的,因此不能直

    2024年02月12日
    浏览(50)
  • [VUE]Element_UI 实现TreeSelect 树形选择器

    最近在做一个人员管理系统,在增改用户信息时,可能会设置用户所在的部门,因为部门是多级的,于是想到用Element_UI的TreeSelect组件实现 效果: 安装完成后,打开package.json 可以看到@riophae/vue-treeselect的版本: 在需要使用TreeSelect的组件中引入 并将Treeselect加到components中:

    2024年02月09日
    浏览(41)
  • element ui datepicker时间控件实现范围选择周,季,年。

    因项目要求,需日,周,月,季,年五种日期范围选择器,故参考文章(在末尾)后分享 一.效果图     二、版本及下载 1.实现需要修改源码,目前修改的版本为2.15.3,所以想要实现该方法,请先将elementui升级或者降到2.15.3. 2.将lib包替换到node_module/element-ui下的lib lib包下载地

    2024年01月17日
    浏览(45)
  • 【vue组件】使用element-ui 实现三级联动下拉选择

    实现的思路是第一个下拉选择在选择了选项后将该选项的信息传递到接口请求下一个选项的内容,依次类推 然后在清除了上一级选择的选项后要将其次级和子孙级的选项都清除(包括选择里的列表内容) 下面看具体代码: 效果图:

    2024年02月11日
    浏览(62)
  • Element-ui(Cascader 级联选择器)实现三级联动

    市区表: 县区表: 省级表: Controller层: service层 serviceimpl实现 mapper层实现 映射省下面所有的市 映射市下面所有的县 查询所有的区县 对应的省JavaBean 对应市JavaBean 对应的县区JavaBean 级联选择器 方法: 注意:级联选择器需要保持和后端映射保持一致回显数据 element-ui官网级

    2024年02月11日
    浏览(67)
  • 基于Vue+Element-Ui开发的月日组件,可以选择月份和天数小插件(新版本)

    最近有粉丝在使用的过程中发现不能满足自己项目上的需求,评论说不支持 placeholder 以及更改输入框大小 size ,所以又赶紧更新了一个版本,之前是1.0.7,现在新版本为1.1.0,点击查看之前的老版本 本组件是基于Vue和Element-ui,因Element官方组件库没有可以选择月份和天数的组

    2023年04月19日
    浏览(76)
  • element ui 中 Cascader 级联选择器实现 动态加载 动态禁用 入门

    实现效果 当点击的 根选项 有 子选项 时,会向后台发送请求,并且接收数据实现动态加载。 点击特殊选项时,可以禁用其他选项。 相关代码 props prop handleClassOrStudentChange

    2024年02月11日
    浏览(43)
  • vue element ui el-date-picker(日期选择器)实现联动联级选择效果。

    页面上有三个 日期选则器。第一个只能选择月份,第二个是 年月, 第三个是年月日 。 然后第一个选择完毕 第二个、第三个自动带出年 。第二个选择月 第三个自动带出月。  思路: 就是 一个简单的赋值 。第一个 change里 给第二个和第三个赋值 。第二个change里给第三个赋

    2024年02月16日
    浏览(61)
  • element-ui实现日期选择器最近一周,上一周,下一周功能

    界面部分代码: js部分:

    2024年02月11日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包