vue3.0横向TimeLine组件封装

为满足开发需求,基于VUE3.0重新封装的TimeLine组件,其中部门标签引用了antd的popover组件,可根据需求自行修改。

效果图:

下面的代码:

<template>
    <ul class="timeline-wrapper" @scroll="scrollEvent">
        <li class="timeline-item" v-for="item in timelineList" :key="item.id">
            <div class="timeline-box">
                <div class="out-circle">
                    <div class="in-circle"></div>
                    <div class="timeline-date">
                        <a-popover placement="bottom" trigger="hover" width="200" title="简介">
                            <template #content>
                                <p>{{item.content}}</p>
                            </template>

                           <a-button style="background-color: #39c1e0;font-family: DS-Digital;font-size: 16px" type="primary">{{item.date}}</a-button>
                        </a-popover>
                        <!-- <el-popover
                                 placement="bottom"
                                 title="标题"
                                 width="200"
                                 trigger="hover"
                                 :content="item.content"
                         >
                             <el-button type="text" slot="reference" class="father-text">{{
                                 item.date
                                 }}</el-button>
                         </el-popover>-->
                    </div>
                </div>
                <div
                        class="long-line"
                        v-show="item.isShow"
                        :style="`width:${item.children ? (item.children.length + 1) * 100 : 1 * 100}px`">
                    <div
                            v-for="(subItem, index) in item.children"
                            :key="subItem.id"
                            class="sub-item-box"
                    >
                        <span>{{ subItem.name + ":" + subItem.num }}人</span>
                        <!-- 根据奇数偶数来判断向上展示还是向下展示 -->
                        <div :class="`sub-line-box ${index % 2 === 0 ? 'top-line-box' : 'bottom-line-box'}`" v-show="subItem.content">
                            <div :class="`children-line-box ${index % 2 === 0 ? 'top-line' : 'bottom-line' }`"></div>
                            <div :class="`children-box ${index % 2 === 0 ? 'top-children-box' : 'bottom-children-box'}`">
                                {{ subItem.content }}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </li>
    </ul>
</template>

<script>
    import {defineComponent, reactive, toRefs} from "vue";

    export default {
        name: "timeLine",
        props: {
            timelineList: {
                type: Array,
                default: () => {
                    return [
                        {
                            id: 1,
                            date: "2018",
                            title: "2018",
                            content: "2018年初,5周年庆典",
                            isShow: true,
                            children: [],
                        },
                        {
                            id: 2,
                            date: "2019",
                            title: "2019",
                            content: "2019年,6周年庆典",
                            isShow: true,
                            children: [
                                {
                                    name: "创始团队",
                                    num: 5,
                                    content: "股份分红",
                                },
                            ],
                        },
                        {
                            id: 3,
                            date: "2020",
                            title: "2020",
                            content: "2020年,进行团队规模扩招",
                            isShow: true,
                            children: [
                                {
                                    name: "内务部",
                                    num: 10,
                                    content: "负责接待",
                                },
                                {
                                    name: "技术部",
                                    num: 20,
                                    content: "前端:5人,后端10人,测试5人",
                                },
                            ],
                        },
                        {
                            id: 4,
                            date: "2021",
                            title: "2021",
                            content: "2021年,拟定增设岗位",
                            isShow: true,
                            children: [
                                {
                                    name: "xxx总经理",
                                    num: 3,
                                    content: "负责事务为XXX",
                                },
                                {
                                    name: "xxx总经理部",
                                    num: 2,
                                    content: "负责事务为XXX",
                                },
                                {
                                    name: "总裁办xxx",
                                    num: 2,
                                    content: "负责事务为XXX",
                                },
                            ],
                        },
                        {
                            id: 5,
                            date: "2022",
                            title: "2022",
                            content: "2022年",
                            isShow: true,
                            children: [
                                {
                                    name: "商务洽谈",
                                    num: 2,
                                    content: "对外合作",
                                },
                            ],
                        },
                        {
                            id: 6,
                            date: "2022",
                            title: "2022",
                            content: "2022年",
                            isShow: true,
                            children: [
                                {
                                    name: "商务洽谈",
                                    num: 2,
                                    content: "对外合作",
                                },
                            ],
                        },
                        {
                            id: 7,
                            date: "2022",
                            title: "2022",
                            content: "2022年",
                            isShow: true,
                            children: [
                                {
                                    name: "商务洽谈",
                                    num: 2,
                                    content: "对外合作",
                                },
                            ],
                        },

                    ];
                },
            },
        },
        setup(props, ctx) {
            const timelineList = props.timelineList;
            const scrollEvent = (e) => {
                this.$emit("scrollEvent", e);
            }
            const handleBottomClick = () => {
                this.$emit("handleBottomClick");
            }
            return {
                timelineList,
                scrollEvent,
                handleBottomClick
            }
        }
    }
</script>

<style scoped>
    .timeline-wrapper::-webkit-scrollbar {
        width: 4px;
        height: 12px;
    }
    .timeline-wrapper::-webkit-scrollbar-thumb {
        border-radius: 10px;
        -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.3);
        opacity: 0.2;
        background-color: #dadada;

    }
    .timeline-wrapper::-webkit-scrollbar-track {
        border-radius: 10px;
        -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.3);


    }
    ul.timeline-wrapper {
// DS-Digital该字体样式为自定义
        font-family: DS-Digital;
        list-style: none;
        margin: 0;
        padding: 200px 20px;
        white-space: nowrap;
        overflow-x: scroll;

    }

    /* 时间线 */
    .timeline-item {
        position: relative;
        display: inline-block;
    }

    .timeline-item .timeline-box {
        text-align: center;
        display: flex;
        align-items: center;
    }

    .timeline-item .timeline-box .out-circle {
        width: 12px;
        height:12px;
        background: #39c1e0;
        box-shadow: 0px 4px 12px 0px rgba(0, 0, 0, 0.4);
        border-radius: 50%;
        display: flex;
        align-items: center;
        cursor: pointer;
    }

    .timeline-item .timeline-box .out-circle .in-circle {
        width: 8px;
        height: 8px;
        margin: 0 auto;
        background: rgba(14, 116, 218, 1);
        border-radius: 50%;
        box-shadow: 0px 4px 12px 0px rgba(0, 0, 0, 0.1);
    }

    .timeline-item .timeline-box .out-circle .timeline-date {
        color: #333;
        margin-top: 55px;
    }

    .timeline-item .timeline-box .out-circle .timeline-date .father-text {
        font-weight: 900;
        font-size: 16px;
        margin-left: -15px;
    }

    .long-line {
        height: 2px;
        background: rgba(14, 116, 218, 0.2);
        box-shadow: 0px 4px 12px 0px rgba(0, 0, 0, 0.3);
        display: flex;
        flex-direction: revert;
        justify-content: space-around;
    }

    .long-line .sub-item-box {
        margin-top: -20px;
        position: relative;
    }

    .long-line .sub-item-box .sub-line-box {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    .long-line .sub-item-box .sub-line-box .children-line-box {
        width: 0px;
        border-left: 1px solid rgba(14, 116, 218, 0.3);
    }

    .long-line .sub-item-box .sub-line-box .children-box {
        flex-wrap: wrap;
        display: flex;
        justify-content: center;
        align-items: center;
        border: 1px solid rgba(14, 116, 218, 0.3);
        white-space: break-spaces;
        text-align: center;
        padding: 5px;
    }

    .long-line .top-line-box {
        margin-top: -100px;
        height: 60px;
    }

    .long-line .bottom-line-box {
        margin-top: 5px;
        height: 150px;
    }

    .long-line .top-line {
        height: 65px;
    }

    .long-line .bottom-line {
        height: 120px;
    }

    .long-line .top-children-box {
        margin-top: -90px;
           background-color: #e2e2e2;
        border-radius: 5px;
        width: 100px;
    }

    .long-line .bottom-children-box {
        background-color: #e2e2e2;
        border-radius: 5px;
        width: 150px;
    }

    .timeline-content {
        box-sizing: border-box;
        margin-left: 20px;
        height: 106px;
        padding: 0 0 0 20px;
        text-align: left;
        margin-bottom: 30px;
    }

    .timeline-content .timeline-title {
        font-size: 14px;
        word-break: break-all;
        margin-bottom: 16px;
        color: #333;
        font-weight: 500;
        /*display: inline;*/
    }

    .timeline-content .timeline-desc {
        font-size: 14px;
        color: #999999;
    }

    .timeline-item:last-of-type .timeline-content {
        margin-bottom: 0;
    }

</style>

希望能对大家有所帮助!

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值