这个组件的话 需要三个第三方依赖

npm install --save chinese-lunar-calendar sass sass-loader element-ui

sass因为我这里 还是习惯写sass样式 毕竟真的方便啊
chinese-lunar-calendar 是一款将日期转为农历的工具
element-ui主要是表格真的方便

在 项目src下的main.js入口文件 挂一下element-ui

import ElementUI from 'element-ui';
Vue.use(ElementUI)

组件参考代码如下

<template>
    <div class = "root">
        <el-table
            :data="tableData"
            style="width: 100%"
            height="calc(100vh - 40px)"
            border
            v-if = "isminkey"
        >
            <el-table-column
                label="周日"
            >
                <template slot-scope="scope">
                    <section
                        class = "module"
                    >
                        <header>
                            <span>{{ scope.row.sunday&&scope.row.sunday.text?scope.row.sunday.text:'' }}</span>
                            <span
                              style = "margin-left: 11px;"
                            >{{ scope.row.sunday&&scope.row.sunday.calendar?scope.row.sunday.calendar:'' }}</span>
                        </header>
                        <section class = "agendaTheme">
                            <div
                              class = "commandLine"
                              v-if = "scope.row.sunday&&scope.row.sunday.list"
                              v-for = "item in scope.row.sunday.list"
                              :key = "item.id"
                            >
                                <div :style = "`background: ${colorMap[item.type]}`"></div>
                                <span>{{ item.name }}</span>
                            </div>
                        </section>
                    </section>
                </template>
            </el-table-column>
            <el-table-column
                label="周一"
            >
                <template slot-scope="scope">
                    <section
                        class = "module"
                    >
                        <header>
                            <span>{{ scope.row.Monday&&scope.row.Monday.text?scope.row.Monday.text:'' }}</span>
                            <span
                              style = "margin-left: 11px;"
                            >{{ scope.row.Monday&&scope.row.Monday.calendar?scope.row.Monday.calendar:'' }}</span>
                        </header>
                        <section class = "agendaTheme" v-if = "scope.row.Monday&&scope.row.Monday.list">
                            <div
                              class = "commandLine"
                              v-for = "item in scope.row.Monday.list"
                              :key = "item.id"
                            >
                                <div :style = "`background: ${colorMap[item.type]}`"></div>
                                <span>{{ item.name }}</span>
                            </div>
                        </section>
                    </section>
                </template>
            </el-table-column>
            <el-table-column
                label="周二"
            >
                <template slot-scope="scope">
                    <section
                        class = "module"
                    >
                        <header>
                            <span>{{ scope.row.Tuesday&&scope.row.Tuesday.text?scope.row.Tuesday.text:'' }}</span>
                            <span
                              style = "margin-left: 11px;"
                            >{{ scope.row.Tuesday&&scope.row.Tuesday.calendar?scope.row.Tuesday.calendar:'' }}</span>
                        </header>
                        <section class = "agendaTheme" v-if = "scope.row.Tuesday&&scope.row.Tuesday.list">
                            <div
                              class = "commandLine"
                              v-for = "item in scope.row.Tuesday.list"
                              :key = "item.id"
                            >
                                <div :style = "`background: ${colorMap[item.type]}`"></div>
                                <span>{{ item.name }}</span>
                            </div>
                        </section>
                    </section>
                </template>
            </el-table-column>
            <el-table-column
                label="周三"
            >
                <template slot-scope="scope">
                    <section
                        class = "module"
                    >
                        <header>
                            <span>{{ scope.row.Wednesday&&scope.row.Wednesday.text?scope.row.Wednesday.text:'' }}</span>
                            <span
                              style = "margin-left: 11px;"
                            >{{ scope.row.Wednesday&&scope.row.Wednesday.calendar?scope.row.Wednesday.calendar:'' }}</span>
                        </header>
                        <section class = "agendaTheme" v-if = "scope.row.Wednesday&&scope.row.Wednesday.list">
                            <div
                              class = "commandLine"
                              v-for = "item in scope.row.Wednesday.list"
                              :key = "item.id"
                            >
                                <div :style = "`background: ${colorMap[item.type]}`"></div>
                                <span>{{ item.name }}</span>
                            </div>
                        </section>
                    </section>
                </template>
            </el-table-column>
            <el-table-column
                label="周四"
            >
                <template slot-scope="scope">
                    <section
                        class = "module"
                    >
                        <header>
                            <span>{{ scope.row.Thursday&&scope.row.Thursday.text?scope.row.Thursday.text:'' }}</span>
                            <span
                              style = "margin-left: 11px;"
                            >{{ scope.row.Thursday&&scope.row.Thursday.calendar?scope.row.Thursday.calendar:'' }}</span>
                        </header>
                        <section class = "agendaTheme" v-if = "scope.row.Thursday&&scope.row.Thursday.list">
                            <div
                              class = "commandLine"
                              v-for = "item in scope.row.Thursday.list"
                              :key = "item.id"
                            >
                                <div :style = "`background: ${colorMap[item.type]}`"></div>
                                <span>{{ item.name }}</span>
                            </div>
                        </section>
                    </section>
                </template>
            </el-table-column>
            <el-table-column
                label="周五"
            >
                <template slot-scope="scope">
                    <section
                        class = "module"
                    >
                        <header>
                            <span>{{ scope.row.Friday&&scope.row.Friday.text?scope.row.Friday.text:'' }}</span>
                            <span
                              style = "margin-left: 11px;"
                            >{{ scope.row.Friday&&scope.row.Friday.calendar?scope.row.Friday.calendar:'' }}</span>
                        </header>
                        <section class = "agendaTheme" v-if = "scope.row.Friday&&scope.row.Friday.list">
                            <div
                              class = "commandLine"
                              v-for = "item in scope.row.Friday.list"
                              :key = "item.id"
                            >
                                <div :style = "`background: ${colorMap[item.type]}`"></div>
                                <span>{{ item.name }}</span>
                            </div>
                        </section>
                    </section>
                </template>
            </el-table-column>
            <el-table-column
                label="周六"
            >
                <template slot-scope="scope">
                    <section
                        class = "module"
                    >
                        <header>
                            <span>{{ scope.row.saturday&&scope.row.saturday.text?scope.row.saturday.text:'' }}</span>
                            <span
                              style = "margin-left: 11px;"
                            >{{ scope.row.saturday&&scope.row.saturday.calendar?scope.row.saturday.calendar:'' }}</span>
                        </header>
                        <section class = "agendaTheme" v-if = "scope.row.saturday&&scope.row.saturday.list">
                            <div
                              class = "commandLine"
                              v-for = "item in scope.row.saturday.list"
                              :key = "item.id"
                            >
                                <div :style = "`background: ${colorMap[item.type]}`"></div>
                                <span>{{ item.name }}</span>
                            </div>
                        </section>
                    </section>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script>
import { getLunar } from 'chinese-lunar-calendar'
export default {
    data() {
        return {
            DateConversion: {
                0: "周日",
                1: "周一",
                2: "周二",
                3: "周三",
                4: "周四",
                5: "周五",
                6: "周六",
            },
            monthComparison: {
                1: 31,
                2: null,
                3: 31,
                4: 30,
                5: 31,
                6: 30,
                7: 31,
                8: 31,
                9: 30,
                10: 31,
                11: 30,
                12: 31
            },
            tableData: [],
            minutesTheMeeting: {
                "2023-05-13":[
                    {
                        id: 1,
                        type: 1,
                        name: "09:00 这是他人同步的时间计划内容"
                    },
                    {
                        id: 2,
                        type: 0,
                        name: "11:00 这是事件名称"
                    }
                ],
                "2023-05-02":[
                    {
                        id: 1,
                        type: 1,
                        name: "09:00 这是他人同步的时间计划内容"
                    },
                    {
                        id: 2,
                        type: 0,
                        name: "11:00 这是事件名称"
                    }
                ],
                "2023-05-18":[
                    {
                        id: 1,
                        type: 1,
                        name: "09:00 这是他人同步的时间计划内容"
                    },
                    {
                        id: 2,
                        type: 0,
                        name: "11:00 这是事件名称"
                    },
                    {
                        id: 3,
                        type: 2,
                        name: "13:00 数据管理测试"
                    },
                    {
                        id: 4,
                        type: 0,
                        name: "13:00 时间管理"
                    },
                    {
                        id: 5,
                        type: 0,
                        name: "13:00 时间管理"
                    },
                    {
                        id: 6,
                        type: 0,
                        name: "13:00 时间管理"
                    },
                    {
                        id: 7,
                        type: 0,
                        name: "13:00 时间管理"
                    }
                ]
            },
            colorMap: {
                0: "#21B1FF",
                1: "#2ECC71",
                2: "#F8A124"
            },
            isminkey: true
        }
    },
    methods: {
        ObtainPlan(date) {
            const { minutesTheMeeting } = this;
            return new Promise((resolve)=>{
                setTimeout(function(){
                    if(minutesTheMeeting[date]){
                        resolve(minutesTheMeeting[date]);
                    }else{
                        resolve([]);
                    }
                },50)
            })
        },
        ateToString(year,month,day) {
            var dateTime = year+'-' +
            (month.length <= 1?("0"+month):month)+
            '-' +
            (day.length <= 1?("0"+day):day)
            return dateTime
        },
        getLunar(date,number) {
            let data = getLunar(date.year, date.month, number);
            return data.dateStr.split("月")[1]?data.dateStr.split("月")[1]:data.dateStr;
        },
        backDay(year) {
            return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)?29:28;
        },
        identify(currentDate,date) {
            this.ObtainPlan(this.ateToString(String(date.year), String(date.month), String(currentDate))).then(list=>{
                if(this.tableData.length) {
                    let tableData = this.tableData[this.tableData.length - 1];
                    if(!tableData.Monday || !tableData.Monday.text) {
                        tableData.Monday = {
                            text: currentDate,
                            calendar: this.getLunar(date,currentDate),
                            list
                        }
                    } else if(!tableData.Tuesday || !tableData.Tuesday.text) {
                        tableData.Tuesday = {
                            text: currentDate,
                            calendar: this.getLunar(date,currentDate),
                            list
                        }
                    } else if(!tableData.Wednesday || !tableData.Wednesday.text) {
                        tableData.Wednesday = {
                            text: currentDate,
                            calendar: this.getLunar(date,currentDate),
                            list
                        }
                    } else if(!tableData.Thursday || !tableData.Thursday.text) {
                        tableData.Thursday = {
                            text: currentDate,
                            calendar: this.getLunar(date,currentDate),
                            list
                        }
                    } else if(!tableData.Friday || !tableData.Friday.text) {
                        tableData.Friday = {
                            text: currentDate,
                            calendar: this.getLunar(date,currentDate),
                            list
                        }
                    } else if(!tableData.saturday || !tableData.saturday.text) {
                        tableData.saturday = {
                            text: currentDate,
                            calendar: this.getLunar(date,currentDate),
                            list
                        }
                    } else {
                        this.tableData.push({
                            sunday: {
                                text: currentDate,
                                calendar: this.getLunar(date,currentDate),
                                list
                            }
                        })
                    }
                } else {
                    this.tableData.push({
                        sunday: {
                            text: currentDate,
                            calendar: this.getLunar(date,currentDate),
                            list
                        }
                    })
                }
                this.isminkey = false;
                this.$nextTick(()=>{
                    this.isminkey = true;
                })
            }).catch(err=>{})
        },
        RotaryCalendar(years,month,index) {
            let theSameDay = new Date(years);
            if((index+1) == 1) {
                years += "-01";
                if(theSameDay.getDay() != 0) {
                    let Day = theSameDay.getDay();
                    let daiyear = theSameDay.getFullYear();
                    let base;
                    if(month == 1){
                        base = 12;
                        daiyear -= 1;
                    }else{
                        base = (Number(month) - 1);
                    }

                    for(let i = Day;i > 0;i--) {
                        let currentDate = this.monthComparison[base] - (i-1);
                        this.identify(currentDate,{
                            year: daiyear,
                            month: base
                        });
                    }
                }
                this.identify(1,{
                    year: theSameDay.getFullYear(),
                    month: theSameDay.getMonth() + 1
                });
            } else if((index+1) == this.monthComparison[Number(month)]) {
                years += `-${this.monthComparison[Number(month)]}`;
                let theSameDay = new Date(years);
                this.identify(
                    (index+1),
                    {
                        year: theSameDay.getFullYear(),
                        month: theSameDay.getMonth() + 1
                    }
                );
                if(theSameDay.getDay() != 6) {
                    let Day = theSameDay.getDay();
                    let daiyear = theSameDay.getFullYear();
                    let base;
                    if(month == 12) {
                        daiyear += 1;
                        base = 1;
                    }else{
                        base = (Number(month) + 1);
                    }
                    let min = 1;
                    for(let i = Day;i < 6;i++) {
                        this.identify(min,{
                            year: daiyear,
                            month: base
                        });
                        min ++;
                    }
                }
            } else {
                this.identify(
                    (index+1),
                    {
                        year: theSameDay.getFullYear(),
                        month: theSameDay.getMonth() + 1
                    }
                );
            }
        },
        getMonthlyObject(years) {
            let date = years?new Date(years):new Date();
            if(!years) {
                years = `${date.getFullYear()}-${date.getMonth() + 1}`
            }
            this.monthComparison[2] = this.backDay(date.getFullYear());
            let month = years.split("-")[1];
            month = Number(month);
            this.tableData = [];
            for(let i = 0;i < this.monthComparison[month];i++) {
                this.RotaryCalendar(years,month,i);
            }
            console.log(this.tableData);
        },
    },
    created() {
        this.getMonthlyObject();
    }

}
</script>

<style lang='scss' scoped>
.module{
    width: calc(100% - 32px);
    height: 141px;
    padding: 16px;
    display: flex;
    flex-direction:column;
    header{
        padding: 0;
        text-align: center;
        font-size: 14px;
        color: #999999;
        margin-bottom: 12px;
    }
    .agendaTheme{
        width: 100%;
        flex: 1;
        overflow: auto;
        .commandLine{
            width: 100%;
            display: flex;
            align-items: center;
            height: 20px;
            font-size: 12px;
            div{
                height: 4px;
                width: 4px;
                margin: 0 4px;
                border-radius: 50%;
            }
            span{
                display: inline-block;
                height: 20px;
                line-height: 20px;
                width: calc(100% - 12px);
                white-space: nowrap;
                overflow: hidden;
                text-overflow:ellipsis; 
            }
        }
    }
}
</style>
<style scoped>
.root >>> .el-table .has-gutter tr{
    height: 48px;
}
.root >>> .el-table th.el-table__cell>.cell{
    text-align: center;
    font-size: 14px;
    font-family: Microsoft YaHei-Regular, Microsoft YaHei;
    font-weight: 400;
    color: #333333;
}
</style>

效果大概是这样
参考企业微信日程 通过vue+elementUi编写一个按月统计会议的日程计划组件-LMLPHP
可以获取到这个月所有关联的周的日期 并转成农历日期 同时我有判断 如果一号不是周日 就继续去取上一个月的日期 保证第一个是周日
然后最后一天不是周六 也会去下一个月继续取日期 其中也考虑到了 12 或 1月 去去年12 下一年1月接着取的逻辑

然后 minutesTheMeeting存了会议 因为考虑大家可能要用接口获取 所以这里写了定时器获取 模仿异步操作

同时 样式上 高度超出滚动 横向超出文本给省略号都有处理
如果大家有兴趣二开 能有所帮助 就太好了

05-23 20:32