自制时间轴组件封装

最新项目的一个时间轴选中样式,磨了我很久,刚开始想的是找网上的插件,但是发现没有,

先给大家看一下我要完成的样式(使用该组件我指定的年限范围是一年,大家可以根据自己的需求,稍作更改)

 

就是图片下方的时间轴,要根据上面时间的选择范围变化,发现网上没有,于是自己和同事一起手写了一个。

先上代码

<template>
    <div class="drag-wrep">
        <ul class="list">
            <li class="time start" ref="Start"></li>
            <li
                v-for="(item, index) in endWeek - startWeek"
                :key="index + 'px'"
                class="time"
                :style="'left:' + (startInit + 17 * item) + 'px'"
            ></li>
            <li class="time end" ref="End"></li>
            <li class="item-li" v-for="(item, index) in 53" :key="index"></li>
        </ul>
        <ul class="list list-month">
            <li
                :class="{
                    'month-start': day < 10,
                    'month-center': day >= 10 && day <= 20,
                    'month-end': day > 20
                }"
                class="item-month"
                v-for="item in month"
                :key="item.id"
            >
                {{ item.name }}
            </li>
        </ul>
    </div>
</template>

<script>
const initMonth = [
    {
        name: "1月",
        id: 1
    },
    {
        name: "2月",
        id: 2
    },
    {
        name: "3月",
        id: 3
    },
    {
        name: "4月",
        id: 4
    },
    {
        name: "5月",
        id: 5
    },
    {
        name: "6月",
        id: 6
    },
    {
        name: "7月",
        id: 7
    },
    {
        name: "8月",
        id: 8
    },
    {
        name: "9月",
        id: 9
    },
    {
        name: "10月",
        id: 10
    },
    {
        name: "11月",
        id: 11
    },
    {
        name: "12月",
        id: 12
    }
];
export default {
    props: {
        daterange: {
            type: [Number, String, Array, Object],
            default: () => [
                parseInt(new Date("2020-09-30T16:00:00.000Z").valueOf()),
                parseInt(new Date("2020-10-30T16:00:00.000Z").valueOf())
            ]
        }
    },
    data() {
        return {
            startInit: 0, // 左边的初始位置
            startTime: 0,
            endTime: 0,
            startWeek: 0,
            endWeek: 0,

            month: [],
            day: new Date().getDate()
        };
    },
    created() {
        this.dealTimeAxis();
    },
    methods: {
        dealTimeAxis() {
            // 处理时间轴
            let month = new Date().getMonth() + 1;
            let year = new Date().getFullYear();
            let newArr = initMonth.filter(item => item.id <= month);
            if (month != 12) {
                newArr[0].name = `${year}年1月`;
            }
            let oldArr = [];
            for (let i = month + 1; i <= 12; i++) {
                oldArr.push({
                    name: `${i}月`,
                    id: i
                });
            }
            this.month = oldArr.concat(newArr);
        },
        dealStartTime(val) {
            // 处理开始时间
            this.startTime = parseInt(
                new Date().valueOf() - new Date(val).valueOf()
            );
            this.startWeek =
                53 - Math.ceil(this.startTime / (24 * 60 * 60 * 1000) / 7);
            this.startInit = this.startWeek * 17;
            this.$refs.Start.style.left = this.startInit + "px";
        },
        dealEndTime(val) {
            this.endTime = parseInt(
                new Date().valueOf() - new Date(val).valueOf()
            );
            this.endWeek =
                53 - Math.ceil(this.endTime / (24 * 60 * 60 * 1000) / 7);
            this.$refs.End.style.left = this.endWeek * 17 + "px";
        }
    }
};
</script>

<style lang="scss" scoped>
.drag-wrep {
    margin-top: 100px;
    width: 100%;
    height: 100px;
    // background-image: linear-gradient(to bottom right, red, yellow);
    .list {
        display: flex;
        position: relative;
        .time {
            position: absolute;
            top: 0;
            width: 15px;
            height: 7px;
            background: #bac1cc;
            margin: 1px;
            cursor: pointer;
        }
        .start {
            left: -1700px;
        }
        .end {
            left: -1700px;
        }
        .item-li {
            width: 15px;
            height: 7px;
            background: #e8f0fe;
            margin: 1px;
        }
    }
    .list-month {
        width: 901px;
        justify-content: space-between;
        .item-month {
            width: 77px;
            font-size: 12px;
            font-weight: 400;

            color: #757575;
        }
        .month-start {
            text-align: right;
        }
        .month-center {
            text-align: center;
        }
        .month-end {
            text-align: left;
        }
    }
}
</style>

就是,这个组件,先给大家讲一下思路。

首先是样式,通过ul,和li实现。因为我们是一个格子是一周的时间算下来一年大概要53个,通过循环,先将格子实现出来,再修改样式

然后先设置list为相对定位,然后里面再定三个li,这三个li就是被选中的样式,设置为绝对定位,每个格子的大小大概是17px。

     <ul class="list">
            <li class="time start" ref="Start"></li>
            <li
                v-for="(item, index) in endWeek - startWeek"
                :key="index + 'px'"
                class="time"
                :style="'left:' + (startInit + 17 * item) + 'px'"
            ></li>
            <li class="time end" ref="End"></li>
            <li class="item-li" v-for="(item, index) in 53" :key="index"></li>
        </ul>

然后通过接收外面传过来的起始时间和结束时间来实现选中样式。

然后在用一个昂发来处理时间轴的位置。和显示的文字内容。

posted @ 2020-11-19 14:12  web~Song  阅读(282)  评论(0编辑  收藏  举报