Element-plus封装季度选择器el-quart-picker

效果:

:先上效果

使用:

这里的vue3 ts不做类型限制,可以后期自行加约束。

父组件中使用子组件:

<template>

    <el-quarter-picker @change="getQuart" ref="quaRef" v-model="quartDate" />

    <div @click="onClick" >点击</div>

</template>

<script  lang="ts" setup>

import { ref } from 'vue';

import ElQuarterPicker from "../components/ElQuarterPicker.vue";

const quartDate = ref('')

const quaRef = ref<any>(null)

const getQuart = (date:any)=>{

  console.log(date,"<====v-date");

  console.log(quartDate.value,"<====v-model");

}

const onClick = ()=>{

  quaRef.value?.inputFocus()

}

</script>

主要是当选择年和季度时触发change回调,这里接收date参数,为2023年第一季度的三个月,起始日期和终止日期。后面季度也是入此。

onClick函数主要是点击右侧按钮聚焦输入框,显示popver内容。

子组件代码:ElQuarterPicker

<template>

  <div class="el-quarter-picker">

    <el-popover :visible="visible" :width="322" placement="bottom-start" trigger="click">

      <div>

        <div class="top-box"> <el-icon @click="preYear">

          <DArrowLeft />

        </el-icon>

          <span>{{ currYear }} 年</span>

          <el-icon @click="nextYear">

            <DArrowRight />

          </el-icon>

        </div>

        <div class="content-box">

          <span :style="{ color: i.color }" @click="handleQuart(i)" v-for="i in quartlist" :key="i.id">{{ i.label

            }}</span>

        </div>

      </div>

      <template #reference>

        <el-input v-model="innerValue"  @focus="onFocus" ref="inputRef" @blur="onBlur"

                  :placeholder="placeholder" :prefix-icon="Calendar" :readonly="false" >

          <template #suffix>

            <el-icon @click="clear" v-show="clearVisble"><CircleClose/></el-icon>

          </template>

        </el-input>

      </template>

    </el-popover>

  </div>

</template>

<script setup lang="ts">

import { ref, computed, reactive, watch, nextTick } from 'vue';

import { Calendar, DArrowRight, DArrowLeft, CircleClose } from '@element-plus/icons-vue'

const props = defineProps({

  placeholder: {

    type: String,

    default: '选择季度'

  },

  modelValue: {

    type: String,

    default: ''

  },

})

const emit = defineEmits(['change', 'update:modelValue'])

// v-model 双向绑定

const innerValue = computed({

  get() {

    return props.modelValue

  },

  set(value) {

    emit('update:modelValue', value)

  }

})


 

const visible = ref(false)

const currYear = ref<any>('')

const quartlist = ref<any>([

  {

    label: '第1季度',

    id: 1,

    color: "var(--el-datepicker-text-color)"

  }, {

    label: '第2季度',

    id: 2,

    color: "var(--el-datepicker-text-color)"

  }, {

    label: '第3季度',

    id: 3,

    color: "var(--el-datepicker-text-color)"

  }, {

    label: '第4季度',

    id: 4,

    color: "var(--el-datepicker-text-color)"

  }

])

const currQuart = reactive<any>({})

currQuart.value = quartlist.value[0]

const getCurrYear = () => {

  let date = new Date()

  currYear.value = date.getFullYear()

}

getCurrYear()


 

// 获取现在的年份季度

function getCurrQuarter() {

  const now = new Date();

  const month = now.getMonth() + 1; // 月份从 0 开始计数,需要加 1

  let index = 0

  if (month <= 3) {

    index = 0;

  } else if (month <= 6) {

    index = 1;

  } else if (month <= 9) {

    index = 2;

  } else {

    index = 3;

  }

  // 高亮当前季度

  quartlist.value[index].color = "var(--el-color-primary)"

}

getCurrQuarter()

const startDate = ref([

  '-01-01',

  '-04-01',

  '-07-01',

  '-10-01',

])

const endDate = ref([

  '-03-31',

  '-06-30',

  '-09-30',

  '-12-31',

])

// 可以根据传来的默认日期 进行回显 自行拓展

// const setCurrQuart = ()=>{

//   console.log(innerValue.value);

// }

// setCurrQuart()


 

const inputRef = ref<any>(null)

const inputFocus = ()=>{

  inputRef.value?.focus()

}

defineExpose({

  inputFocus

})

const nextYear = () => {

  // 获取焦点防止丢失焦点隐藏

  inputFocus()

  let year = new Date(new Date().setFullYear(currYear.value + 1)).getFullYear()

  currYear.value = year

  innerValue.value = currYear.value + '-' + currQuart.value.label

  let emitDate = {

    startDate: currYear.value + startDate.value[currQuart.value.id - 1],

    endDate: currYear.value + endDate.value[currQuart.value.id - 1],

  }

  emit('change', emitDate)

}

const preYear = () => {

  inputFocus()

  let year = new Date(new Date().setFullYear(currYear.value - 1)).getFullYear()

  currYear.value = year

  innerValue.value = currYear.value + '-' + currQuart.value.label

  let emitDate = {

    startDate: currYear.value + startDate.value[currQuart.value.id - 1],

    endDate: currYear.value + endDate.value[currQuart.value.id - 1],

  }

  emit('change', emitDate)

}



 

const handleQuart = (item: any) => {

  quartlist.value.forEach((v: any) => {

    v.color = "var(--el-datepicker-text-color)"

    if (v.id == item.id) {

      v.color = "var(--el-color-primary)"

    }

  });

  currQuart.value = item

  let emitDate = {

    startDate: currYear.value + startDate.value[currQuart.value.id - 1],

    endDate: currYear.value + endDate.value[currQuart.value.id - 1],

  }

  emit('change', emitDate)

  innerValue.value = currYear.value + '-' + currQuart.value.label

  nextTick(()=>{

    inputRef.value?.blur()

    visible.value = false

    console.log(inputRef.value.blur);

  })

}

const clearVisble = ref(false)

const clear = ()=>{

  innerValue.value = ''

  let emitDate = {

    startDate: '',

    endDate: '',

  }

  emit('change', emitDate)

}

const onFocus = ()=>{

  visible.value =true

}

const onBlur = ()=>{

  visible.value =false

}

watch(()=>innerValue.value,(val)=>{

  // 内容不为空时显示清除

  nextTick(()=>{

    clearVisble.value = !!val

  })

})


 

</script>

<style scoped>

.el-quarter-picker {

  display: inline-block;

}

.top-box {

  font-size: 16px;

  cursor: pointer;

  display: flex;

  padding-bottom: 12px;

  align-items: center;

  justify-content: space-between;

  border-bottom: 1px solid var(--el-border-color-lighter);

}

.content-box {

  width: 100%;

  height: 100px;

  display: flex;

  padding-top: 12px;

  flex-wrap: wrap;

}

.content-box>span {

  width: 148px;

  height: 40px;

  text-align: center;

  display: flex;

  align-items: center;

  justify-content: center;

  cursor: pointer;

}

</style>

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值