原文:Element calendar农历日历 - Artemis6 - 博客园 (cnblogs.com)
element日历calendar组件上月、今天、下月、日历块点击事件及模板源码_vue.js_脚本之家 (jb51.net)
一、日历内部样式调整
lement组件calendar目前不支持农历日历,故引用中国农历(阴阳历)和西元阳历即公历互转JavaScript库。
自定义该组件主要为了实现多选日期 和 高亮显示节假日的功能。显示效果如下:

1、为了能用简单的html实现样例程序,将calendar.js的export去掉,通过JS引用的方式实现。
<!--vue引入 --> <script src="https://cdn.staticfile.org/vue/2.5.2/vue.min.js"></script> <!--element-ui引入组件 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <!--calendar引入 --> <script src="calendar.js"></script>
<!-- element-ui引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
2、添加el-calendar组件。通过设置名为 dateCell 的 scoped-slot 来自定义日历单元格中显示的内容。在 scoped-slot 可以获取到 date(当前单元格的日期), data(包括 type,isSelected,day 属性)。
<div id="app">
<el-calendar v-model="value" style=" 820px">
<template slot="dateCell" slot-scope="{date, data}">
<div :class="{ selected : isSelected(date, data) }">
<div class="solar">{{ data.day.split('-')[2] }}</div>
<div class="lunar" :class="{ festival : isFestival(date, data) }">{{ solarToLunar(date, data) }}</div>
</div>
</template>
</el-calendar>
</div>
3、JavaScript实现是否选中、自定义日历显示内容的功能
var Main = {
data() {
return {
// 设置value,会自动显示value对应月份,可以设置为selectedDates的第一个日期
value: '2020-04-12',
// 根据selectedDates设置选中日期
selectedDates: ['2020-04-12','2020-04-15','2020-04-24']
}
},
methods: {
// 是否选中日期
isSelected : function(slotDate, slotData) {
return this.selectedDates.includes(slotData.day)
},
// 是否节假日
isFestival(slotDate, slotData) {
let solarDayArr = slotData.day.split('-');
let lunarDay = calendar.solar2lunar(solarDayArr[0], solarDayArr[1], solarDayArr[2])
// 公历节日农历节日农历节气
let festAndTerm = [];
festAndTerm.push(lunarDay.festival == null ? '' : ' ' + lunarDay.festival)
festAndTerm.push(lunarDay.lunarFestival == null ? '' : '' + lunarDay.lunarFestival)
festAndTerm.push(lunarDay.Term == null ? '' : '' + lunarDay.Term)
festAndTerm = festAndTerm.join('')
return festAndTerm != ''
},
// 公历转农历
solarToLunar(slotDate, slotData) {
let solarDayArr = slotData.day.split('-');
let lunarDay = calendar.solar2lunar(solarDayArr[0], solarDayArr[1], solarDayArr[2])
// 农历日期
let lunarMD = lunarDay.IMonthCn + lunarDay.IDayCn
// 公历节日农历节日农历节气
let festAndTerm = [];
festAndTerm.push(lunarDay.festival == null ? '' : ' ' + lunarDay.festival)
festAndTerm.push(lunarDay.lunarFestival == null ? '' : '' + lunarDay.lunarFestival)
festAndTerm.push(lunarDay.Term == null ? '' : '' + lunarDay.Term)
festAndTerm = festAndTerm.join('')
return festAndTerm == '' ? lunarMD : festAndTerm
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
4、CSS实现自定义显示效果
/**隐藏上一月、本月、下一月*/
.el-calendar__button-group {
display: none;
}
/**月份居中*/
.el-calendar__title {
100%;
text-align: center;
}
/**日期div的样式*/
.el-calendar-table tr td:first-child {
border-left: 0px;
}
.el-calendar-table td {
min-height: 110px;
min- 110px;
border-right: 0px;
}
.el-calendar-table td.is-selected {
background-color: white;
}
.el-calendar-table .el-calendar-day {
height: 100%;
padding: 0px;
text-align: center;
}
.el-calendar-table .el-calendar-day > div {
height: 104px;
}
/**日期div的样式-公历*/
.el-calendar-table .el-calendar-day > div .solar {
padding-top: 30px;
}
/**日期div的样式-农历*/
.el-calendar-table .el-calendar-day > div .lunar {
padding-top: 10px;
}
/**日期div的样式-选中*/
.el-calendar-table .el-calendar-day > div.selected {
background-color: #fef2f2;
border: 3px solid #fb0;
border-radius: 20px;
}
/**本月周末设置为红色*/
.el-calendar-table .current:nth-last-child(-n+2) .solar {
color: red;
}
/**本月农历设置为灰色*/
.el-calendar-table .current .lunar {
color: #606266;
}
/**本月农历节日设置为红色*/
.el-calendar-table .current .lunar.festival {
color: red;
}
/**禁用点击效果*/
/*.el-calendar-table td {*/
/*pointer-events: none;*/
/*}*/
二、日历点击事件

<template>
<div>
<el-card class="_calendar">
<el-container>
<el-main>
<el-card>
<el-calendar v-model="value" :first-day-of-week="7">
<!-- 这里使用的是 2.5 slot 语法,对于新项目请使用 2.6 slot 语法-->
<template slot="dateCell" slot-scope="{date, data}">
<div slot="reference" class="div-Calendar" @click="calendarOnClick(data)">
<p :class="data.isSelected ? 'is-selected' : ''">
{{ data.day.split('-').slice(1).join('-') }}
<i
:class="[data.isSelected ?'el-icon-check':'']"
></i>
<i v-if="_.indexOf(isArrange, data.day)>0" class="el-icon-s-claim"></i>
<!-- <i class="el-icon-coffee-cup"></i> -->
</p>
</div>
</template>
</el-calendar>
</el-card>
</el-main>
<el-aside width="40%" style="overflow: hidden;">
<el-card>
<div class="el-calendar__header">
<div class="el-calendar__title">排班详情</div>
<div class="el-calendar__button-group">
<div class="el-button-group">
<button
type="button"
class="el-button el-button--plain el-button--mini"
@click="saveOnClick"
>
<span>新增</span>
</button>
</div>
</div>
</div>
<div class="calendar-info">
<div style="padding: 15px;">
<div role="alert" class="el-alert el-alert--success is-dark" @click="infoOnClick">
<i class="el-alert__icon el-icon-success is-big"></i>
<div class="el-alert__content">
<span class="el-alert__title is-bold">2020-06-19 9:00~11:00</span>
<p class="el-alert__description">值班人员:张三、李四、王五</p>
<p class="el-alert__description">携带设备:123547、985431、745481</p>
<i class="el-alert__closebtn el-icon-close" @click.stop="infoDel"></i>
</div>
</div>
<div role="alert" class="el-alert el-alert--info is-dark" @click="infoOnClick">
<i class="el-alert__icon el-icon-info is-big"></i>
<div class="el-alert__content">
<span class="el-alert__title is-bold">2020-06-19 9:00~11:00(待审核)</span>
<p class="el-alert__description">值班人员:张三、李四、王五</p>
<p class="el-alert__description">携带设备:123547、985431、745481</p>
<i class="el-alert__closebtn el-icon-close"></i>
</div>
</div>
<div role="alert" class="el-alert el-alert--warning is-dark" @click="infoOnClick">
<i class="el-alert__icon el-icon-warning is-big"></i>
<div class="el-alert__content">
<span class="el-alert__title is-bold">警告提示的文案</span>
<p class="el-alert__description">文字说明文字说明文字说明文字说明文字说明文字说明</p>
<i class="el-alert__closebtn el-icon-close"></i>
</div>
</div>
<div role="alert" class="el-alert el-alert--error is-dark" @click="infoOnClick">
<i class="el-alert__icon el-icon-error is-big"></i>
<div class="el-alert__content">
<span class="el-alert__title is-bold">错误提示的文案</span>
<p class="el-alert__description">文字说明文字说明文字说明文字说明文字说明文字说明</p>
<i class="el-alert__closebtn el-icon-close"></i>
</div>
</div>
</div>
</div>
</el-card>
</el-aside>
</el-container>
</el-card>
<calendarDrawer ref="calendarDrawer"></calendarDrawer>
<calendarForm ref="calendarForm"></calendarForm>
</div>
</template>
<script>
import calendarDrawer from "./calendar-drawer.vue";
import calendarForm from "./calendar-form.vue";
export default {
components: { calendarDrawer, calendarForm },
data: function() {
return {
value: new Date(),
isArrange: [
"2020-06-08",
"2020-06-09",
"2020-06-10",
"2020-06-11",
"2020-06-17",
"2020-06-18"
]
};
},
created: function() {
this.$nextTick(() => {
// 点击前一个月
let prevBtn = document.querySelector(
".el-calendar__button-group .el-button-group>button:nth-child(1)"
);
prevBtn.addEventListener("click", e => {
console.log(this.data);
this.$notify({
title: "上一月",
message: "上个月头天:" + this.value,
type: "success",
position: "top-left"
});
});
//点击下一个月
let nextBtn = document.querySelector(
".el-calendar__button-group .el-button-group>button:nth-child(3)"
);
nextBtn.addEventListener("click", () => {
console.log(this.value);
this.$notify({
title: "下一月",
message: "下个月头天:" + this.value,
type: "warning",
position: "top-left"
});
});
//点击今天
let todayBtn = document.querySelector(
".el-calendar__button-group .el-button-group>button:nth-child(2)"
);
todayBtn.addEventListener("click", () => {
this.$notify.info({
title: "今天",
message: "今天:" + this.value,
position: "top-left"
});
});
});
},
mounted: function() {},
methods: {
//点击日期块
calendarOnClick(e) {
console.log(e);
// this.isArrange.push("2020-06-19");
this.$notify.error({
title: "日历块点击",
message: e,
position: "top-left"
});
},
//点击信息块
infoOnClick() {
this.$refs.calendarDrawer.drawer = true;
},
//新增排班
saveOnClick() {
this.$refs.calendarForm.dialogFormVisible = true;
},
//删除排班
infoDel() {
this.$confirm("此操作将永久删除该排班, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$message({
type: "success",
message: "删除成功!"
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
}
}
};
</script>
<style scoped>
.is-selected {
color: #1989fa;
}
.p-popover {
text-align: center;
}
._calendar {
height: 99.5%;
100%;
}
.el-main {
padding: 0px;
overflow: hidden;
}
.calendar-info {
height: 94%;
overflow: auto;
}
.el-alert {
margin: 15px 0px;
}
.el-alert:hover {
transform: scale(1.02);
}
.el-alert:active {
transform: scale(1.01);
}
</style>
<style >
._calendar .div-Calendar {
height: 125px;
box-sizing: border-box;
padding: 8px;
}
._calendar .el-calendar-table .el-calendar-day {
padding: 0px;
height: 125px;
}
._calendar .el-container,
._calendar .el-calendar {
height: 100%;
}
._calendar .el-card__body {
padding: 0px;
}
</style>
