Element Plus中el-calendar的cell-class-name属性失效问题咨询
问题:Element Plus el-calendar 的 cell-class-name 属性不生效,是否已不再支持?
我尝试用cell-class-name属性给el-calendar的日历单元格设置颜色,但该属性完全没生效。查Element Plus官方文档没找到相关说明,但ChatGPT说这个属性可以用。
依赖版本:
"core-js": "^3.8.3", "element-plus": "^2.2.32", "vue": "^3.2.13", "vue-router": "^4.0.3"
代码示例:
<template> <el-calendar v-model="currentDate" :range="range" :formatter="formatter" :cell-class-name="cellClass" /> </template> <script lang="ts"> import { defineComponent, ref, onMounted } from 'vue'; import { ElCalendar } from 'element-plus'; export default defineComponent({ components: { ElCalendar, }, setup() { const currentDate = ref(new Date()); const range = ref<[Date, Date]>([new Date("2023-02-26"), new Date("2023-03-25")]); const checkedDates = ref<Date[]>([]); const formatter = (date: Date) => { const day = date.getDate(); return day.toString(); }; const cellClass = (date: Date) => { console.log('cellClass called'); if (checkedDates.value.includes(date)) { console.log('date is checked'); return 'blue'; } return ''; }; console.log('data init'); const fetchData = async () => { // const response = await fetch('/api/getCheckedDates'); // const data = await response.json(); // checkedDates.value = data.checkedDates.map((d: string) => new Date(d)); checkedDates.value = [new Date("2023-03-01"), new Date("2023-03-02")]; console.log('fetch data'); }; onMounted(() => { fetchData(); }); return { currentDate, range, formatter, cellClass, }; }, }); </script> <style> .blue { color: rgb(212, 66, 66); } </style>
控制台日志:
data init fetch data
日志显示cellClass函数根本没被调用。
解答
首先明确:Element Plus 的 el-calendar 组件从一开始就没有cell-class-name这个属性——这个属性是 Element UI(Vue 2版本)的el-calendar具备的,Element Plus重构组件时并未保留该API,官方文档里没有说明是因为它从来不是Element Plus的API,ChatGPT的信息有误。
要实现给指定日期单元格设置样式的需求,可以用以下两种替代方案:
方案一:使用自定义单元格内容的作用域插槽
通过date-cell插槽完全自定义单元格结构,直接给对应元素绑定类名:
<template> <el-calendar v-model="currentDate" :range="range"> <template #date-cell="{ data }"> <div :class="['calendar-cell', getCellClass(data.date)]"> {{ data.day.split('-').pop() }} </div> </template> </el-calendar> </template> <script lang="ts"> import { defineComponent, ref, onMounted } from 'vue'; import { ElCalendar } from 'element-plus'; export default defineComponent({ components: { ElCalendar }, setup() { const currentDate = ref(new Date()); const range = ref<[Date, Date]>([new Date("2023-02-26"), new Date("2023-03-25")]); const checkedDates = ref<Date[]>([]); const getCellClass = (date: Date) => { // 注意:直接用数组includes比较Date对象会因为引用不同失败,需要转成字符串或时间戳对比 const dateStr = date.toISOString().split('T')[0]; const hasMatch = checkedDates.value.some(d => d.toISOString().split('T')[0] === dateStr); return hasMatch ? 'blue' : ''; }; const fetchData = async () => { checkedDates.value = [new Date("2023-03-01"), new Date("2023-03-02")]; }; onMounted(() => { fetchData(); }); return { currentDate, range, getCellClass }; }, }); </script> <style scoped> .calendar-cell { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .blue { color: rgb(212, 66, 66); font-weight: bold; } </style>
方案二:通过深度选择器修改默认单元格样式
如果不想完全自定义单元格,可以通过日期的data-date属性(Element Plus默认给每个单元格绑定的属性)来定位目标日期,结合深度选择器修改样式:
<template> <el-calendar v-model="currentDate" :range="range" :formatter="formatter" /> </template> <script lang="ts"> import { defineComponent, ref, onMounted } from 'vue'; import { ElCalendar } from 'element-plus'; export default defineComponent({ components: { ElCalendar }, setup() { const currentDate = ref(new Date()); const range = ref<[Date, Date]>([new Date("2023-02-26"), new Date("2023-03-25")]); const checkedDates = ref<Date[]>([]); const formatter = (date: Date) => { return date.getDate().toString(); }; const fetchData = async () => { checkedDates.value = [new Date("2023-03-01"), new Date("2023-03-02")]; }; onMounted(() => { fetchData(); }); return { currentDate, range, formatter, checkedDates }; }, }); </script> <style scoped> /* 深度选择器,根据Element Plus的单元格结构调整 */ :deep(.el-calendar-table__row td) { position: relative; } /* 针对目标日期设置样式 */ :deep(.el-calendar-table__row td[data-date="2023-03-01"]) .el-calendar-day { color: rgb(212, 66, 66); } :deep(.el-calendar-table__row td[data-date="2023-03-02"]) .el-calendar-day { color: rgb(212, 66, 66); } </style>
注意点:
- 直接用
Array.includes()比较Date对象会失败,因为每个Date实例都是不同的引用,需要转成统一格式的字符串或时间戳对比。 - 方案一中的
date-cell插槽是Element Plus官方提供的自定义方式,完全可控,推荐使用。 - 方案二中的深度选择器需要根据Element Plus的实际DOM结构调整,版本更新可能会导致选择器失效。
内容的提问来源于stack exchange,提问作者livid
相关产品推荐
相关产品推荐

