今天公司要求做日程 这体的话 和企业微信的日程功能挺想的
也没有找到特别好的工具 就直接自己手敲了一个
先看效果
vue参照企业微信日程写一个小组件-LMLPHP
vue参照企业微信日程写一个小组件-LMLPHP
vue参照企业微信日程写一个小组件-LMLPHP

因为样式使用 sass 写的 所以 项目中要引入 sass
感兴趣的 可以把代码拿去二开一下

<template>
    <section class = "skeletonPositioning">
        <section class = "support">
        </section>
        <section class = "scrollingElement">
            <div class = "timeNode">
                <div><span class = "displacement"></span></div>
                <div
                    v-for = "item in timeSet"
                    :key = "item"
                >
                    <span class = "displacement">{{ refraction(item)?item:'' }}</span>
                </div>
            </div>
            <div class = "ConversionList">
                <div class = "changeHands"></div>
                <div
                    v-for = "item in timeSet"
                    :key = "item"
                    class = "changeHands"
                >
                    <div 
                        v-if = "refraction(item)"
                        class = "box"
                        v-bind:class="{Excessive:captureHourlyAccuracy(item) == getDate()}"
                    >
                    </div>
                    <div
                        class = "mark"
                        v-if = "captureHourlyAccuracy(item) == getDate()&&refraction(item)"
                    ></div>
                </div>
                <div
                    v-for = "(item,index) in schedule"
                    :key = "item.id"
                    class = "ReflectTheProcess"
                    :style = "`
                        width: calc(${analysisLength(item,0,index)}% - 20px);
                        background-color: ${ colorMap[item.type] };
                        height: ${analysisLength(item,1,index)}px;
                        top: ${analysisLength(item,2,index)}px;
                        left: ${analysisLength(item,3,index)}%;
                    `"
                >
                    <div>{{ item.title }}</div>
                    <div>{{ `${item.start.time}-${item.end.time}` }}</div>
                </div>
            </div>
        </section>
    </section>
</template>

<script>
export default {
    data() {
        return {
            timeSet: [
                "01: 00", "01: 15", "01: 30", "01: 45", "02: 00", "02: 15", "02: 30", "02: 45", "03: 00", "03: 15", "03: 30",
                "03: 45", "04: 00", "04: 15", "04: 30", "04: 45", "05: 00", "05: 15", "05: 30", "05: 45", "06: 00", "06: 15", "06: 30", "06: 45",
                "07: 00", "07: 15", "07: 30", "07: 45", "08: 00", "08: 15", "08: 30", "08: 45", "09: 00", "09: 15", "09: 30", "09: 45", "10: 00",
                "10: 15", "10: 30", "10: 45", "11: 00", "11: 15", "11: 30", "11: 45", "12: 00", "12: 15", "12: 30", "12: 45", "13: 00", "13: 15",
                "13: 30", "13: 45", "14: 00", "14: 15", "14: 30", "14: 45", "15: 00", "15: 15", "15: 30", "15: 45", "16: 00", "16: 15", "16: 30",
                "16: 45", "17: 00", "17: 15", "17: 30", "17: 45", "18: 00", "18: 15", "18: 30", "18: 45", "19: 00", "19: 15", "19: 30", "19: 45",
                "20: 00", "20: 15", "20: 30", "20: 45", "21: 00", "21: 15", "21: 30", "21: 45", "22: 00", "22: 15", "22: 30", "22: 45", "23: 00",
                "23: 15", "23: 30", "23: 45", "00: 00", "00: 30", "00: 45", 
            ],
            schedule: [
                {
                    id: 1,
                    title: "日程测试数据",
                    start:{
                        date: "2022-05-17",
                        time: "09: 00",
                        getWeekDate: "周一 "
                    },
                    end: {
                        date: "2022-05-17",
                        time: "11: 00",
                        getWeekDate: "周一 "
                    },
                    type: 2
                },
                {
                    id: 2,
                    title: "测试高级数据整理",
                    start:{
                        date: "2022-05-17",
                        time: "10: 00",
                        getWeekDate: "周一 "
                    },
                    end: {
                        date: "2022-05-17",
                        time: "11: 00",
                        getWeekDate: "周一 "
                    },
                    type: 1
                },
                {
                    id: 3,
                    title: "高级日程",
                    start:{
                        date: "2022-05-17",
                        time: "11: 00",
                        getWeekDate: "周一 "
                    },
                    end: {
                        date: "2022-05-17",
                        time: "13: 45",
                        getWeekDate: "周一 "
                    },
                    type: 0
                },
                {
                    id: 4,
                    title: "测试参与会议",
                    start:{
                        date: "2022-05-17",
                        time: "03: 00",
                        getWeekDate: "周一 "
                    },
                    end: {
                        date: "2022-05-17",
                        time: "08: 45",
                        getWeekDate: "周一 "
                    },
                    type: 0
                },
                {
                    id: 5,
                    title: "测试控件超过时间管理",
                    start:{
                        date: "2022-05-17",
                        time: "23: 00",
                        getWeekDate: "周一 "
                    },
                    end: {
                        date: "2022-05-17",
                        time: "00: 45",
                        getWeekDate: "周一 "
                    },
                    type: 0
                }
            ],
            colorMap: {
                0: "#D9F2FF",
                1: "#E4FFEF",
                2: "#FFF4E4"
            }

        }
    },
    methods: {
        identificationHeight(item) {
            let height = 0;
            let hibernate = true;
            const { timeSet } = this;
            for(let i = 0;i < timeSet.length;i++){
                if(!hibernate) height += 20;
                if(timeSet[i] == item.start.time) hibernate = false;
                if(timeSet[i] == item.end.time) return height;
            }
            return 0
        },
        comprehensiveOperation(dataObject) {
            let isStart = dataObject.time.split(": ");
            return Number(isStart[0]+isStart[1])
        },
        BeforeAfterInference(item,index) {
            const { schedule,comprehensiveOperation } = this;
            const start = comprehensiveOperation(item.start);
            const end = comprehensiveOperation(item.end);
            let PreCollection = 0;
            let PostSet = 0;
            schedule.map((nomt,onindex) => {
                const itemstart = comprehensiveOperation(nomt.start);
                const itemend = comprehensiveOperation(nomt.end);
                if(itemend >= start&&itemstart <= end) {
                    if(index > onindex) PreCollection++;
                    if(index < onindex) PostSet++;
                }
            })
            return {
                PreCollection,
                PostSet
            }
        },
        stepCountRecord(time) {
            const { timeSet } = this;
            let recordTop = 0;
            for(let i = 0;i < timeSet.length;i++){
                recordTop += 20;
                if(time == timeSet[i]) {
                    return recordTop;
                }
            }
            return recordTop;
        },
        analysisLength(item,type,index) {
            const { stepCountRecord, identificationHeight, BeforeAfterInference } = this;
            switch(type){
                case 0:
                    const data = BeforeAfterInference(item,index);
                    const sum = data.PreCollection+data.PostSet+1;
                    return (1/sum)*100
                break;
                case 1:
                    return identificationHeight(item);
                case 2:
                    return stepCountRecord(item.start.time);
                break;
                case 3:
                    const datas = BeforeAfterInference(item,index);
                    const sums = datas.PreCollection+datas.PostSet+1;
                    const x = (1/sums)*100;
                    return datas.PreCollection*x;
                break;
                default:
                    return 0
                break;
            }
        },
        refraction(str) {
            let isStart = str.split(": ");
            return (isStart[1] == "00");
        },
        captureHourlyAccuracy(str) {
            let isStart = str.split(": ");
            return isStart[0];
        },
        getDate(datemin) {
            var date = datemin?new Date(datemin):new Date();
            var oHour = date.getHours();
            oHour = oHour < 10 ? ("0" + oHour) : oHour;
            return oHour;
        }
    }
}
</script>

<style lang='scss' scoped>
.skeletonPositioning{
    width: 100%;
    height: 100%;
    position: relative;
    .support{
        width: 100%;
        height: 30px;
        position: absolute;
        top: 0;
        background-image: linear-gradient(rgb(244, 243, 243), #FFFFFF);
    }
    .scrollingElement{
        width: 100%;
        height: calc(100% - 30px);
        display: flex;
        overflow-y: auto;
        overflow-x: hidden;
        position: relative;
        z-index: 1;
        border-bottom: 1px solid #DCDFE6;
        .timeNode{
            width: 76px;
            height: auto;
            border-top: 1px solid transparent;
            div{
                width: 100%;
                height: 20px;
                font-size: 14px;
                color: #999999;
                text-align: center;
                position: relative;
                .displacement{
                    position: absolute;
                    top: -7px;
                    width: 100%;
                    left: 0;
                }
            }
        }
        .ConversionList{
            flex: 1;
            border-top: 1px solid #DCDFE6;
            position: relative;
            .changeHands{
                width: 100%;
                height: 20px;
                color: #999999;
                border-left: 1px solid #DCDFE6;
                position: relative;
                .box{
                    height: 0px;
                    border-bottom: 1px solid #DCDFE6;
                }
                .mark{
                    height: 10px;
                    width: 10px;
                    background: rgb(112, 166, 243) !important;
                    margin: auto;
                    position: absolute;
                    top: -5px;
                    left: -5px;
                    border-radius: 50%;
                }
                .Excessive{
                    border-bottom: 1px solid rgb(112, 166, 243) !important;
                }
            }
            .ReflectTheProcess{
                position: absolute;
                text-align: left;
                margin: 0 10px;
                div{
                    text-align: left;
                    padding: 5px 0 0 10px;
                }
            }
        }
    }
}
</style>
05-17 19:35