前提
最近在做一个Vue3新项目,用的是element-plus,发现很多以前在element-ui中用的属性和方法都不管用了。
正好要做时间选择器,记录一下elment-plus中时间选择器的属性和方法的使用。
1. 实现时间限制
1.1 属性pickerOptions不可用的问题
以前在element-ui中都用pickerOptions来限制日期的可选时间范围,如下:
<el-date-picker
v-model="searchForm.orderTime"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:pickerOptions="pickerOptions"
ref="dateDom"
>
</el-date-picker>
data() {
return {
pickerOptions: {
disabledDate(time) {
// 禁止选当天以后的日期
return time.getTime() > Date.now()
}
}
}
},
最近在做一个Vue3新项目,也要实现类似功能,但突然发现pickerOptions不好用了,控制台也没有报错,郁闷坏了。由于之前是在Vue2中使用的pickerOptions属性,本次Vue3使用的是element-plus代替element-ui,猜测使用上会有所区别。
1.2 使用disabled-date解决
element-plus地址:DateTimePicker 日期时间选择器 | Element Plus (element-plus.org)
Vue3中想要实现pickerOptions的功能,可以用disabled-date来代替,如下:
子组件
<el-col
v-for="(item, index) in queryFormArr"
:key="index"
>
<!-- 这里禁掉了用户的修改和清空功能-->
<el-date-picker
:editable="false"
:clearable="false"
v-model="item.val"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
v-if="item.type == 'daterange'"
:disabled="item.disabled"
maxlength="10"
end-placeholder="结束日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
class="font-xs item-form-doc"
:disabled-date="item.options.disabledDate"
@calendar-change="item.options.selectDate"
@change="onChange"
>
</el-col>
子组件script (子组件是vue2的)
data() {
return {
selectedValue:null // 设置鼠标点击日期选中的值,用于计算选中日期前后的不可选日期
queryFormArr:props.queryArr
}
},
methods:{
// 选定两个日期后,清除原来的选中值,取消选中值的日期限制
onChange(){
this.selectedValue = null
}
}
父组件
<query ref="queryRef" :queryArr="queryParams" class="query">
父组件<script>
/**
* 获取日活/月活时间选择器的默认展示时间
* @param isDailyPanel 日活/月活标志
*/
function getTime(isDailyPanel) {
let currentDate = new Date(new Date().getTime() - 24 * 60 * 60 * 1000).toLocaleString() // 当前时间
let sixDaysAgo = new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000).toLocaleString() // 六天前的时间
let lastMonthDate = new Date(new Date().getTime() - 24 * 60 * 60 * 1000 * new Date().getDate()).toLocaleString() // 一个月前的时间:当前日期-本月的天数
let startDay = `${translateDay(sixDaysAgo, lastMonthDate, isDailyPanel)}` // 开始时间
let endDay = `${translateDay(currentDate, lastMonthDate, isDailyPanel)}` // 结束时间
return [startDay, endDay]
}
/**
* 返回开始和结束时间
* @param dayDate 年、月、日时间
* @param monthDate 上个月时间
* @param isDailyPanel 日活/月活标志
*/
function translateDay(dayDate, monthDate, isDailyPanel) {
let [year, month, day] = dayDate.split(' ')[0].split('/')
let lastMonth = monthDate.split(' ')[0].split('/')[1]
// 日活面板默认显示前一天,月活面板显示上个月
return isDailyPanel ? `${year}-${translateTime(month)}-${translateTime(day)}` : `${year}-${translateTime(lastMonth)}`
}
/**
* 限制选择当天以前的日期
* @param date 日期组件自动传入的日期参数
*/
function disabledDate(date) {
let lastDay = new Date(new Date().getTime() - 24 * 60 * 60 * 1000)
let lastMonth = new Date(new Date().getTime() - 24 * 60 * 60 * 1000 * new Date().getDate())
// 日活面板限制日期可选前后1个月,月活面板限制日期可选前后12个月
if (isDailyPanel) {
// 用户已选中一个日期,根据该日期限制可选日期为前后1个月
if (queryRef.value && queryRef.value.selectedValue) {
return (
date.getTime() > lastDay ||
dayjs(date) < dayjs(queryRef.value.selectedValue).subtract(1, 'month').add(1, 'day') ||
dayjs(date) > dayjs(queryRef.value.selectedValue).add(1, 'month').subtract(1, 'day')
)
}
// 用户未选中,限制可选日期为昨天及以前
return date.getTime() > lastDay
} else {
// 用户已选中一个日期,根据该日期限制可选日期为前后12个月
if (queryRef.value && queryRef.value.selectedValue) {
return (
date.getTime() > lastMonth ||
dayjs(date) < dayjs(queryRef.value.selectedValue).subtract(11, 'month') ||
dayjs(date) > dayjs(queryRef.value.selectedValue).add(11, 'month')
)
}
// 用户未选中,限制可选日期为上个月及以前
return date.getTime() > lastMonth
}
}
/**
* 设置当前鼠标选中值
* @param date 日期组件自动传入的日期参数
*/
function selectDate(date) {
queryRef.value.selectedValue = date[0]
}
1.3 属性disabled-date做时间限制
disabled-date方法:用来做日期的时间限制。
需求:
(1)选择了日期时,其他可选日期做限制(选该日期的前后一个月)
(2)没选日期时,应当有一个默认限制(不能选昨天以前的日期)
2. calendar-change选中日期时回调
calendar-change方法:用来设置选中日历日期后的回调。此处用来将鼠标点击选中的日期赋值给selectedValue。
虽然官网声称该方法只对datetimerange生效,但实际该问题已被修复,在2.3.13版本后,该方法对其他类型也生效,建议从2.3.14版本开始使用:
selectedValue:为鼠标点击日期选中的值,我用它来计算选中日期前后的不可选日期。
入参:
这个入参会自动对点击日期排序。
(1)如果时间面板选择一个日期,则date只有选中的一个日期;
(2)如果选择了两个日期,date会对两个日期呈从小到大排序。
这样就保证了date[0]取到的就是点击的日期中的较小值。
(因为我们对选择日期作前后一个月可选限制时,也是针对点击日期的较小值来做限制的)
3. visible-change面板下拉收起回调
入参:
它的入参也有两种情况,true/false。
true:表明此时是点击出现下拉列表
false:表明此时是点击收起下拉列表
这个方法这里没使用,作为了解
4. 引入中文显示
时间选择器的官网组件默认英文,这里需要用中文显示
main.ts
import ElementPlus from 'element-plus'
import locale from 'element-plus/dist/locale/zh-cn'
const app = createApp(App)
app.use(ElementPlus,{locale}) //中文
5. 时间选择器样式问题
5.1 取消当前日期的加粗+蓝色高亮显示
原效果:当前日期(5月27日)有默认的加粗及蓝色高亮展示,需要恢复成和5月28日同样的样式
找一个公共组件,写入下列样式:
// 时间选择器-日单位-取消【当前日期】默认的加粗+蓝色高亮显示
.el-date-table td.today .el-date-table-cell__text{
color: #A8ABB2 !important;
font-weight: normal !important;
}
效果:
5.2 取消当前月份默认的加粗显示
原效果:当前月份(五月)有默认的加粗显示效果
找一个公共组件,写入下列样式:
// 时间选择器-月单位-取消【当前月份】默认的加粗显示
.el-month-table td.today .cell{
font-weight: normal !important;
}
效果:
6. 安装完element-plus样式不生效问题
el-date-picker长这样,能忍?
别忘记在main.ts引入element的css文件
import ElementPlus from 'element-plus'
import locale from 'element-plus/dist/locale/zh-cn' // 引入中文
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import 'element-plus/dist/index.css' // 引入样式
......
const app = createApp(App)
app.use(ElementPlus, { locale })
// 注册图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
....