先上实现样式
需求:日期分为三种情况
1,安全的日期,展示为绿色背景颜色
2,不安全日期,展示为红色背景颜色,鼠标滑过显示不安全内容
3,正常无数据的日期,展示默认蓝色
使用了elementui里的日历组件
<el-calendar v-model="value" :first-day-of-week="7" class="lar-el-calendar">
<template slot="dateCell" slot-scope="{data}">
<el-popover
placement="top-start"
:disabled="visible"
trigger="hover"
:content="detail"
>
<div
slot="reference"
v-on:mouseover="
(data)"
:class="labelBg(data)"
>
{{ data.day.split('-').slice(2).join('-') }}
</div>
</el-popover>
</template>
</el-calendar>
注意点:弹出框不能写嵌套内容,否则会加载多余的日期,导致样式错乱。
渲染的数据:
this.calendarData = {
dangerProduceCount: '111', // 非安全生产天数
securityProduceCount: '111', // 安全生产天数
detail: [
{
date: '2022-06-06', // 日期
securityFlag: 'N', // 是否安全
content: '常州1号线,常州1号线',
},
{
date: '2022-06-05', // 日期
securityFlag: 'Y', // 是否安全
content: '',
},
],
}
=====中间省略====
data() {
return {
value: new Date(),
visible: false,
detail: '测试1232312',
}
},
methods: {
// 判断class名
labelBg(event) {
const findItem = this.findSameDay(event)
if (findItem) {
// 当前是危险的
if (findItem.securityFlag === 'Y') {
return 'safe'
} else if (findItem.securityFlag === 'N') {
return 'danger'
}
} else {
return ''
}
},
//判断当前是否需要展示弹窗
isShowpop(event) {
this.detail = ''
const findItem = this.findSameDay(event)
//当前是危险的
if (findItem && findItem.securityFlag === 'N') {
this.detail = findItem.content
this.visible = false
} else {
//当前安全或者没有数据
this.visible = true
}
},
//拆分的公用方法,寻找当前在数据中存在的日期
findSameDay(event) {
return this.dataContent.detail.find((item) => {
console.log('item.date ', item.date)
// console.log('newDate ', newDate)
return item.date === event.day
})
},
},
通过动态class判断当前样式
通过后端数据返回对应控制当前是否是危险日期,判断弹出框是否显示。
修改日历组件原有的css样式:
.danger {
background: red;
height: 100%;
}
.safe {
background: linear-gradient(90deg, #2ff38f 0%, rgba(65, 176, 145, 0.4) 100%);
height: 100%;
}
.normal {
background: linear-gradient(90deg, #0e315a 0%, rgba(48, 65, 98, 0.4) 100%);
height: 100%;
}
/deep/ .el-calendar-table {
padding: 0;
}
/deep/.el-calendar__header {
padding: 0;
}
/deep/.el-calendar__body {
padding: 2px;
border-bottom: none;
}
/deep/.el-calendar__title {
color: rgba(216, 239, 255, 1);
}
.lar-el-calendar {
background: RGBA(11, 35, 80, 1);
}
/deep/.el-calendar-table > thead {
display: none;
}
/deep/.el-calendar-table .el-calendar-day {
height: 2rem;
}
/deep/.el-calendar-table .current {
box-shadow: inset 0rem 0rem 0.5rem 0rem rgba(75, 112, 186, 0.4);
border-radius: 0.13rem;
color: rgba(216, 239, 255, 1);
background: linear-gradient(90deg, #0E315A 0%, rgba(48, 65, 98, 0.4) 100%);
}
/deep/.el-calendar {
height: 14.5rem;
background: linear-gradient(
180deg,
#082451 0%,
rgba(21, 37, 82, 0.8) 57%,
rgba(32, 38, 82, 0.15) 100%
);
}
// 除去日历表格的padding
/deep/ .el-calendar-table .el-calendar-day {
padding: 0;
}
// 修改当天日期样式
// /deep/ .el-calendar-table td.is-today {
// background-color: #fff;
// }
// // 修改选中日期样式
// /deep/ .el-calendar-table td.is-selected {
// background-color: #fff;
// }
// 当天的样式
/deep/ .el-calendar-table td.is-today {
background: linear-gradient(
180deg,
#082451 0%,
rgba(21, 37, 82, 0.8) 57%,
rgba(32, 38, 82, 0.15) 100%
);
}
// 修改上个月样式
/deep/ .el-calendar-table .el-calendar-day {
height: 1.8rem;
font-size: 12px;
text-align: center;
color: RGBA(95, 112, 148, 1);
}
// 修改下个月样式
/deep/ .el-calendar-table:not(.is-range) td.prev {
.calendarFont {
color: RGBA(95, 112, 148, 1);
}
pointer-events: none;
}
按钮事件:由于需求不涉及到当前日期,所以需要把按钮隐藏掉,封装组件需要切换日期时向外emit切换后的日期。
created: function () {
this.$nextTick(() => {
// 计算出后端需要的日期格式用于向外抛出
let date = Moment(new Date(this.value)).format('YYYY-MM')
// 点击前一个月
let prevBtn = document.querySelector(
'.el-calendar__button-group .el-button-group>button:nth-child(1)'
)
prevBtn.addEventListener('click', (e) => {
this.$emit('changeDate', date)
})
//点击下一个月
let nextBtn = document.querySelector(
'.el-calendar__button-group .el-button-group>button:nth-child(3)'
)
nextBtn.addEventListener('click', (e) => {
this.$emit('changeDate', date)
})
//点击今天
let todayBtn = document.querySelector(
'.el-calendar__button-group .el-button-group>button:nth-child(2)'
)
// 此处由于需求隐藏掉
todayBtn.style.display = 'none'
})
},