记录改造elementui日历组件实例(日报月报)

本文详细描述了如何改造ElementUI的calendar组件,以适应日报和月报的需求,包括添加高亮显示功能、全部按钮控制以及处理月历的自定义显示和点击事件。
摘要由CSDN通过智能技术生成

前言 

任务是要做一个日报月报的填写和展示,以上是做出来的效果图,以下是任务要点:

1.左边是日历(月历)展示,有上月今天下月和全部(点击右边会显示所有日报数据)供用户选择。

2.右边是切换选择后对应日报月报的卡片展示区域,

3.左边日历(月历)上对应日期有日报月报数据的会特殊显示(绿色圈),点击日期右边能获取到对应日期的日报月报数据

4.初始左边日历(月历)显示的是本月存在日报数据,初始右边显示的是全部日报数据

1.改造elementui calendar日历组件

基础日历显示如下

所以得用样式穿透实现相应的效果,这里我是循环匹配需要高亮显示的日期,进行覆盖显示(如果码友大大们有更好显示高亮日期的写法,分享分享啊),其中DateList是初始化页面时获取的当月日报(上面前言要点中的第四点)。其中parseTime是时间格式化的方法,getShow是加在日期上面的点击事件方法,getDay是格式化日期的方法(去0)。

<template>
<div class="calendar">
                        <el-calendar v-model="value" style="width:355px ; height: 400px;">
                            <div slot="dateCell" slot-scope="{ data }">
                                <div style="position:relative">
                                    <div class="calendar-day" @click="getShow(parseTime(data.day, '{y}-{m}-{d}'))">{{
                                        getDay(data.day) }}</div>
                                    <div v-for="(item, index) in DateList" :key="index">
                                        <div v-if="data.day.split('-')[1] == item.date.split('-')[1]">
                                            <div v-if="item.date.split('-')[2] == data.day.split('-')[2]" class="li-01"
                                                style="position: absolute;top: 0;left: 0px;width: 100%;"
                                                @click="getShow(parseTime(data.day, '{y}-{m}-{d}'))">
                                                {{ getDay(data.day) }}
                                            </div>
                                        </div>
                                        <div v-else>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </el-calendar>
</div>
</template>
<style lang="scss" scoped>
.li-01 {
    width: 31px !important;
    height: 31px;
    background: #fff !important;
    color: #001529 !important;
    border: 1.5px solid #25de9d;
    border-radius: 15px;
    margin-left: 50%;
    transform: translate(-15px);
    line-height: 30px;
    text-align: center;
    font-size: 16px;
    top: 5px;
}

::v-deep .el-calendar-table tr td:first-child {
    border-left: none !important
}

::v-deep .el-calendar-table tr:first-child td {
    border-top: none;
}

::v-deep .el-calendar-table td {
    border-bottom: none;
    border-right: none;
    vertical-align: top;
    -webkit-transition: background-color 0.2s ease;
    transition: background-color 0.2s ease;
}

::v-deep .el-calendar-table .el-calendar-day {
    width: 45px;
    height: 45px;
}

.calendar {
    width: 355px;
    display: block;
    float: left;
    margin: 0px
}

.calendar-day {
    text-align: center;
    line-height: 30px;
    width: 30px;
    height: 30px;
    border: 1px solid rgb(172, 165, 165);
    border-radius: 50%;
}

::v-deep .el-calendar-table thead th {
    padding: 12px 0;
    color: #606266;
    font-weight: normal;
    background-color: #f8f4f4;
}
</style>

 以上可以实现效果

其中我们要改变一般日历组件上面的布局和内容,加上全部按钮,如下

 

 这里我们得在页面初始化的时候给日历组件添加全部按钮元素和给元素添加点击事件代码如下

created(){
            const groupbtn = document.querySelector('.el-button-group')
            const child = document.createElement('button')
            child.innerHTML = `全部`
            child.setAttribute('class', 'el-button el-button--plain el-button--mini')
            groupbtn.appendChild(child)
            child.addEventListener("click", () => {
                this.$set(this.queryParams, 'date', '')
                this.getList()
            });
},

同理,组件上的其他三个按钮也要加上点击事件(上月,今天,下月)

created() {

        this.$nextTick(() => {

            let prevBtn = document.querySelector('.el-calendar__button-group .el-button-group>button:nth-child(1)');
            prevBtn.addEventListener('click', () => {
                this.getInit(this.parseTime(this.value, '{y}-{m}')) //获取左边日历上显示日报日期的方法
                this.getShow(this.parseTime(this.value, '{y}-{m}')) //获取右边卡片内容数据的方法
            })
            let nextBtn = document.querySelector('.el-calendar__button-group .el-button-group>button:nth-child(3)');
            nextBtn.addEventListener('click', () => {
                this.getInit(this.parseTime(this.value, '{y}-{m}'))
                this.getShow(this.parseTime(this.value, '{y}-{m}'))
            })
            let todayBtn = document.querySelector(
                ".el-calendar__button-group .el-button-group>button:nth-child(2)"
            );
            todayBtn.addEventListener("click", () => {
                this.getInit(this.parseTime(this.value, '{y}-{m}'))
                this.getShow(this.parseTime(this.value, '{y}-{m}-{d}'))
            });
            const groupbtn = document.querySelector('.el-button-group')
            const child = document.createElement('button')
            child.innerHTML = `全部`
            child.setAttribute('class', 'el-button el-button--plain el-button--mini')
            groupbtn.appendChild(child)
            child.addEventListener("click", () => {
                this.$set(this.queryParams, 'date', '')
                this.getList()
            });
        })

    },

 如此,日历就改造完成了

2.月历实现

 

月历我是自己手写实现的,代码如下:

其中

style="{ backgroundColor: yearformat + '-' + nawmonthFormat == inityear + '-' + item ? '#f2f8fe' : '', color: yearformat + '-' + nawmonthFormat == inityear + '-' + item ? '#1890ff' : '' }"是判断是否是当月,当月的月期特殊标明。

:class="monthData.indexOf(`${item}`) != -1 ? 'itemmonthA' : 'itemmonth'" 是判断是否是有数据的月份

yearformat   //是点击月历中的上一年下一年按钮,可能会变化的年份

inityear        //是现在的年份

nawmonthFormat //现在的月份,

<div class="calendar">
<el-row :gutter="10">
      <el-col :span="15">
            <el-row style="height: 30px;border: 1px solid #dfdfdf; border-radius: 2px;">
                   <el-col :span="3" class="leftClass" @click.native="getpreYear">
                         <i style="font-size: 20px; font-weight: bold;" class="el-icon-arrow-left"></i>
                   </el-col>
                   <el-col :span="18" class="centerYear">{{ yearformat }}年</el-col>
                   <el-col :span="3" class="rightClass" @click.native="getNextYear">
                         <i style="font-size: 20px; font-weight: bold;" class="el-icon-arrow-right"></i>
                   </el-col>
             </el-row>
                   </el-col>
       <el-col :span="9">
             <div class="tobackNawYear" @click="inityearformat">
                 返回本年
             </div>
             <div class="AllClass" @click="getAll">
                  全部
             </div>
        </el-col>
</el-row>
<div class="monthList">
      <div @click="getshowmonthData(item)" :class="monthData.indexOf(`${item}`) != -1 ? 'itemmonthA' : 'itemmonth'" :style="{ backgroundColor: yearformat + '-' + nawmonthFormat == inityear + '-' + item ? '#f2f8fe' : '', color: yearformat + '-' + nawmonthFormat == inityear + '-' + item ? '#1890ff' : '' }" v-for="(item, index) in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]" :key="index">{{ item }}月
      </div>
</div>
</div>




<style lang="scss" scoped>
.tobackNawYear {
    display: block;
    float: left;
    cursor: pointer;
    width: 50%;
    height: 30px;
    border: 1.2px solid #dcdfe6;
    border-radius: 2px;
    text-align: center;
    color: #606266;
    line-height: 30px;
    font-size: 13px;
}

.tobackNawYear:hover {
    border: 1.2px solid #badeff;
    background-color: #e8f4ff;
    color: #1890ff;
}

.AllClass {
    cursor: pointer;
    display: block;
    float: left;
    width: 38%;
    margin-left: 4%;
    height: 30px;
    border: 1.2px solid #dcdfe6;
    border-radius: 2px;
    text-align: center;
    color: #606266;
    line-height: 30px;
    font-size: 13px;
}

.AllClass:hover {
    border: 1.2px solid #badeff;
    background-color: #e8f4ff;
    color: #1890ff;
}

.centerYear {
    text-align: center;
    line-height: 30px;
    color: #666666;
}

.leftClass {
    height: 30px;
    line-height: 30px;
    text-align: center;
    background-color: #f7f4f4;
}

.rightClass {
    height: 30px;
    line-height: 30px;
    text-align: center;
    background-color: #f7f4f4;
}
.monthList {
    width: 100%;
    display: flex;
    flex-wrap: wrap;

    .itemmonth {
        cursor: pointer;
        width: 50px;
        height: 45px;
        margin-right: 9px;
        margin-top: 20px;
        border: #dfdfdf 1.5px solid;
        border-radius: 3.35px;
        text-align: center;
        line-height: 45px;
        font-size: 14px;
        color: #6a655f;
    }

    .itemmonthA {
        cursor: pointer;
        width: 50px;
        height: 45px;
        margin-right: 9px;
        margin-top: 20px;
        border: #65cea7 1.5px solid;
        border-radius: 3.35px;
        text-align: center;
        line-height: 45px;
        font-size: 14px;
        color: #6a655f;
    }

    .itemmonthA:hover {
        background-color: #f2f8fe;
    }

    .itemmonth:hover {
        background-color: #f2f8fe;
    }
}
</style>

3.其中parseTime、getShow、getDay方法

//parseTime方法
export function parseTime(time, pattern) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
      time = parseInt(time)
    } else if (typeof time === 'string') {
      time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

//getShow方法
getShow(val) {
            if (val) {
                this.$set(this.queryParams, 'date', val)
                this.getList() //调用初始化页面方法(右边卡片展示数据)
            }
        },


//getDay方法
getDay(value) {
            const day = value.split("-")[2]; // 11, 02
            return day.startsWith("0") ? day.slice(1) : day;
        },

总结

以上是实践中我对日月历的改造实现过程,我通过这篇文记录下来,希望也能给看到的码友们一些灵感和启发。

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值