#项目中遇到的需求#
需求:根据后端接口返回的日期数据,能够选择对应范围内的年和月,没有数据的年份的左右箭头隐藏。
项目背景:Vue3+JS+ElementPlus
实现:通过ElementPlus组件库中的el-date-picker日期选择器组件实现。
问题:选择月份的日期选择器并没有提供calendar-change方法去拿到当前面板中的年月,而根据需求需要将没有数据的年份的左右箭头隐藏。
思路:通过原生dom拿到组件标题上面的年份,监听拿到的年份,通过focus时间和年份做对比控制左右箭头的显隐。其中focus和disabledDate 都是组件自带的方法,不了解的可以自行查看elmentPlus官网。

代码逻辑简单易理解,展示如下:
<template>
<el-date-picker v-model="value1" type="monthrange" :disableddate="disabledDate"
:default-value="[new Date('2019'), new Date('2020')]" range-separator="—"
start-placeholder="开始月份" end-placeholder="结束月份" @focus="focus" />
</template>
<script setup>
import { getCurrentInstance, onMounted, ref, watch, defineProps} from 'vue';
const value1 = ref('')
const minTime = ref()
const maxTime = ref()
// 时间选择器的左箭头
const pickerDomLeft = ref(null)
// 时间选择器的dom年份
const headDomDate = ref()
// 时间选择器的右箭头
const pickerDomRight = ref(null)
/**
* 获取日期范围
*/
const getTimeRange = async () => {
const res = await getTableRange()
maxTime.value = dayjs(res.data.max).format('YYYY-MM-DD HH:mm:ss', 'zh-cn')
minTime.value = dayjs(res.data.min).format('YYYY-MM-DD HH:mm:ss', 'zh-cn')
}
/**
* 禁用没有数据的日期
* @param {*} time 当前时间
*/
const disabledDate = (time) => {
const startDate = new Date(minTime.value);
const endDate = new Date(maxTime.value);
return time < startDate || time > endDate;
}
/**
*
* 时间选择器获取焦点事件
* pickerDomLeft,pickerDomRight两个变量存左右箭头的类名
* headDomDate存头部日期的类名
*/
const focus = () => {
if (!headDomDate.value) {
headDomDate.value = document.querySelectorAll('.el-date-range-picker__content .el-date-range-picker__header div')
}
if (!pickerDomLeft.value) {
pickerDomLeft.value = document.querySelector('.el-date-range-picker__header [class*=arrow-left]')
}
if (!pickerDomRight.value) {
pickerDomRight.value = document.querySelector('.el-date-range-picker__header [class*=arrow-right]');
}
// 拆出年份和面板的年份做对比
const headDomDateArr1 = headDomDate.value[0].innerText.split(' ')
const min = minTime.value.slice(0, 4)
pickerDomLeft.value.style.display = min === headDomDateArr1[0] ? 'none' : 'block'
const headDomDateArr2 = headDomDate.value[1].innerText.split(' ')
const max = maxTime.value.slice(0, 4)
pickerDomRight.value.style.display = max === headDomDateArr2[0] ? 'none' : 'block'
}
/**
* 因为elementPlus没有该属性操作方法,通过原生dom实现
* 监听拾取到的左箭头增加点击事件控制箭头显隐
*/
watch(pickerDomLeft, () => {
if (!pickerDomLeft.value) return;
// 给左箭头添加点击事件并监听
pickerDomLeft.value.addEventListener("click", () => {
// 拆出年份和面板的年份做对比
const headDomDateArr1 = headDomDate.value[0].innerText.split(' ')
const min = minTime.value.slice(0, 4)
pickerDomLeft.value.style.display = min === headDomDateArr1[0] ? 'none' : 'block'
// 如果右侧年份比最大时间小-显示
if (headDomDate.value[1].innerText < maxTime.value.slice(0, 4)) {
pickerDomRight.value.style.display = 'block'
}
})
})
/**
* 监听拾取到的右箭头增加点击事件控制箭头显隐
*/
watch(pickerDomRight, () => {
if (!pickerDomRight.value) return;
pickerDomRight.value.addEventListener("click", () => {
// 拆出年份和面板的年份做对比
const headDomDateArr2 = headDomDate.value[1].innerText.split(' ')
const max = maxTime.value.slice(0, 4)
pickerDomRight.value.style.display = max === headDomDateArr2[0] ? 'none' : 'block'
// 如果左侧年份比最小时间小-显示
if (headDomDate.value[0].innerText > minTime.value.slice(0, 4)) {
pickerDomLeft.value.style.display = 'block'
}
})
})
</script>
2959

被折叠的 条评论
为什么被折叠?



