基于项目管理开发需求而封装,可以灵活的输入时间线,并在时间线上,进行不同的计划安排,简单直观,组件引用了antd3.0组件库的popover组件,逻辑清晰简单,可自行更改!

效果图:

代码块:

<template>
    <div class="wapper" id="queryForm">
        <div class="workLine">
            <div v-for="(items,index) in task" :key="index"
                 :style="'width:'+items.Domwidth+'px; margin-left:'+items.width+'px'"
                 class="timetips">
                <a-popover title="计划详情">
                    <template #content>
                        <p>{{items.content}}</p>
                    </template>
                    <a-button style="background-color: white;border: none;text-decoration:underline" type="link">
                        计划({{index+1}})
                    </a-button>
                </a-popover>
                <i class="ri-map-pin-3-fill"/>
            </div>
        </div>
        <div class="lineFATH" style="display: flex;width: 100%;position: relative">
            <div v-for="(item,index) in list" :key="item.id"
                 :style="'left:'+item.width+'px' "
                 class="timeCard">
                <div class="timeCardMid">
                    <p class="timeCardMidLine"/>
                </div>
                <div :class="index===0?'ONE':''||index===(list.length-1)?'TWO':''" class="timeCardBot">
                    {{item.data}}
                </div>
            </div>
        </div>

    </div>
</template>

<script>
    import {toRefs, ref, reactive, nextTick, onMounted, getCurrentInstance} from 'vue'

    export default {
        props: {
            list: {
                type: Array,
                default: [
                    {
                        id: "1",
                        data: " 2022-01-12"
                    },
                    {
                        id: "2",
                        data: "2022-08-12"
                    },
                    {
                        id: "3",
                        data: "2022-03-12"
                    },
                    {
                        id: "4",
                        data: "2022-10-12"
                    },
                    {
                        id: "5",
                        data: "2022-12-12"
                    },
                ],
            },
            task: {
                type: Array,
                default: [
                    {
                        id: "1",
                        startTime: "2022-02-32",
                        endTime: "2022-05-12",
                        content: "这是我的第一个任务"
                    },
                    {
                        id: "2",
                        startTime: "2022-05-32",
                        endTime: "2022-08-12",
                        content: "这是我的第二个任务"
                    },
                    {
                        id: "3",
                        startTime: "2022-08-32",
                        endTime: "2022-11-12",
                        content: "这是我的第三个任务"
                    },
                    {
                        id: "4",
                        startTime: "2022-11-32",
                        endTime: "2022-12-12",
                        content: "这是我的第n个任务"
                    },
                ]
            }

        },
        setup(props) {
            const internalInstance = getCurrentInstance();
            const Array = reactive({
                /*时间轴*/
                list: props.list,
                /* 任务划分区域*/
                task: props.task,
                DomWidth: 0,
                timeWidth: "",
                evenly: '',

            });
            /*处理底部时间轴*/
            const addDays = () => {
                Array.list.forEach((item) => {
                    item.dueTime = Date.parse(item.data);
                });
                /*使用sort对Json数组的数据进行时间从小到大的排序*/
                Array.list.sort(function (a, b) {
                    return a.dueTime - b.dueTime;
                });
                console.log(Array.list)
                /*获取整个时间段的数据的总天数,并除以父级元素宽度,获取每一天元素可以分得的宽度*/
                Array.timeWidth = compareDate(Array.list[0].data, Array.list[Array.list.length - 1].data);
                Array.evenly = (Array.DomWidth / Array.timeWidth).toFixed(0);
                /*将得到的底部时间段,进行计算,分配在主轴线上所占位置*/
                for (let i = 0; i < Array.list.length; i++) {
                    Array.list[i].width = Array.evenly * compareDate(Array.list[0].data, Array.list[i].data)

                }
                /*起止位置分别定位为0以及100%*/
                Array.list[0].width = 0;
                Array.list[Array.list.length - 1].width = Array.DomWidth - 1
                tasks()
            };
            /*处理任务时间轴*/
            const tasks = () => {
                for (let i = 0; i < Array.task.length; i++) {
                    Array.task[i].Domwidth = Array.evenly * compareDate(Array.task[i].startTime, Array.task[i].endTime);

                    if (i === 0) {
                        Array.task[i].width = 0
                    } else {
                        Array.task[i].width = Array.evenly * compareDate(Array.task[i - 1].endTime, Array.task[i].startTime)
                    }
                }
                internalInstance.ctx.$forceUpdate()
            };
            /*计算两个时间之间的天数*/
            const compareDate = (start, end) => {
                if (start === null || start.length === 0 || end === null || end.length === 0) {
                    return 0;
                }
                let arr = start.split("-");
                let starttime = new Date(arr[0], parseInt(arr[1] - 1), arr[2]);
                let starttimes = starttime.getTime();

                let arrs = end.split("-");
                let endtime = new Date(arrs[0], parseInt(arrs[1] - 1), arrs[2]);
                let endtimes = endtime.getTime();

                let intervalTime = endtimes - starttimes;//两个日期相差的毫秒数 一天86400000毫秒
                let Inter_Days = ((intervalTime).toFixed(2) / 86400000) + 1;//加1,是让同一天的两个日期返回一天

                return Inter_Days;
            };

            /*挂载时输出父元素的宽度*/
            onMounted(() => {
                /*或取父级元素的宽高*/
                Array.DomWidth = document.getElementById('queryForm').clientWidth;
                addDays()
            });
            return {
                ...toRefs(Array),
                internalInstance,
                compareDate
            }
        }


    }
</script>

<style scoped>
    .wapper {
        margin: 20px 20px;
        background-color: #39c1e0;
        border: 1px solid #39c1e0;

    }

    p {
        margin: 0;
        padding: 0;
    }

    .timeCard {
        position: absolute;
        top: 0px;
        height: 35px;
        text-align: center;

    }

    .timeCardMid {
        height: 35px;
    }

    .timeCardMidLine {
        height: 35px;
        width: 1px;
        background-color: #39c1e0;
    }

    .timeCardBot {
        height: 35px;
        border-radius: 5px;
        text-align: center;
        line-height: 35px;
        padding: 0 5px;
        position: relative;
        border: 1px solid #d9d9d9;
        top: -0;
        left: -50%;
        width: 100px;

    }

    .workLine {
        display: flex;
    }

    .ri-map-pin-3-fill {
        position: absolute;
        left: 50%;
        top: -66%;
        font-size: 16px;
        color: #3d3d3d;

    }

    .ONE {
        left: -20px !important;
    }

    .TWO {
        left: -80%;
    }

    .timetips {
        background-color: white;
        position: relative;
        border-radius: 5px;
        height: inherit;
        font-size: 12px;
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        justify-content: center;

    }
</style>

希望能够帮助到大家!

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐