Vue时间轴

4 篇文章 0 订阅

之前有这样子的需求没有用第三方插件于是自己写一个简单的时间轴

时间轴滚动条并左右切换滚动条位置相对应移动

在这里插入图片描述

<div class="time-scrollbar">
        <div v-if="timeLineData.length>0" class="scrollbar-content">
          <div class="arrow" @click="clickLeft"> <el-icon :size="40"><ArrowLeft /></el-icon></div>
          <el-scrollbar ref="timeScrollbarRef" @scroll="scrollChange"  always >
            <TimeLine ref="timeLineRef" id="timeLineId" class="time-line" direction="vertical" :stripe="true" sizeIcon="large" 
            :timelineList="timeLineData" :hollowIcon="true" :hasNameCenter="false"/>
          </el-scrollbar>
          <div class="arrow" @click="clickRight"><el-icon :size="40"><ArrowRight /></el-icon></div>
        </div>
        <div v-else class="text-info">暂无数据</div>
   </div>

const clickLeft = () => {
  if(start.value > 0) {
    start.value = start.value-1398
    end.value = end.value-10
    timeScrollbarRef.value.scrollTo(start.value, end.value)
    // 点击更改数据
     // page.value = page.value >=1? 1: page.value-1 
     // getTimeLineData()
  }
}
const scrollChange = (scrollData: any) => {
  start.value = scrollData.scrollLeft
}
const clickRight = () => {
  const contentWidth = document.getElementById('timeLineId')?.offsetWidth as number
  if((end.value + 1398) < contentWidth) {
    start.value = start.value+1398
    end.value = end.value+10
    timeScrollbarRef.value.scrollTo(start.value, end.value)
  }
  //  点击更改数据
  // page.value = page.value+1 
  // getTimeLineData()
}

//TimeLine页面

<template>
  <div class="time-line-box">
    <el-timeline
      :class="{
        timeline: true,
        'timeline-stripe': stripe,
        'timeline-vertical': direction === 'vertical',
        'name-center': hasNameCenter
      }"
      >
      <el-timeline-item
        v-for="(item, index) in timelineList"
        :key="index"
        :timestamp="!$slots.item ? item.time : undefined"
        placement="top"
        center
        :color="item.color"
        :hollow="hollowIcon"
        :size="sizeIcon"
        :icon="hasNameCenter ? () => item.name : undefined"
        :style="
          direction === 'vertical'
            ? `width: calc(${100 / timelineList.length}% - 2px)`
            : 'width: 100%'
        "
        @click="item.onClick"
      >
        <template v-if="$slots.item">
          <slot name="item" :data="item" />
        </template>
        <template v-else>
          <div v-if="!hasNameCenter" class="name">
            {{ item.name }}
          </div>
          <div class="time">
            {{ item.keepTime }}
          </div>
        </template>
      </el-timeline-item>
    </el-timeline>
  </div>
    
</template>
<script lang="ts" setup>
import { PropType } from 'vue'
import { Card } from '@/components'

defineProps({
  stripe: {
    type: Boolean,
    default: false
  },
  direction: {
    type: String as PropType<'horizontal' | 'vertical'>,
    default: 'horizontal'
  },
  timelineList: {
    type: Array as PropType<any[]>,
    default: () => []
  },
  height: {
    type: [Number, String],
    default: () => 150
  },
  hasNameCenter: {
    type: Boolean,
    default: false
  },
  hollowIcon:{
    type: Boolean,
    default: false
  },
  sizeIcon:{
    type: String as PropType<'normal' | 'large'>,
    default: 'normal'
  }
})
</script>
<style lang="scss" scoped>
.time-line-box {
  :deep(.timeline) {
    margin: 0;
    padding: 18px 0 0;
    .el-timeline-item__tail {
      border-left: 2px solid rgba(255, 255, 255, 0.3);
    }
    .el-timeline-item__timestamp {
      margin-bottom: 0;
      padding-top: 0;
    }
    .el-timeline-item__timestamp,
    .el-timeline-item__content {
      font-size: 14px;
      font-weight: normal;
      color: #fff;
    }
    // .el-timeline-item {
    //   width: 100% !important;
    //   // padding: 0 0 10px;
    // }
  }

  :deep(.timeline-vertical) {
    display: flex;
    .el-timeline-item__tail {
      border-left: none;
      border-top: 2px solid rgba(255, 255, 255, 0.3);
      width: 100%;
      position: absolute;
      top: 6px;
    }
    .el-timeline-item__timestamp {
      margin-bottom: 8px;
      padding-top: 4px;
    }
    .el-timeline-item__node {
      left: 35%;
      margin-top: 15px;
      border-color: #037DFF;
    }
    .el-timeline-item__wrapper {
      padding-left: 0;
      position: absolute;
      top: 20px;
      text-align: center;
    }
  }
  :deep(.timeline-stripe) {
    padding-top: 85px;

    .el-timeline-item {
      .el-timeline-item__wrapper {
        transform: translateY(-165%);
      }
      &:nth-child(2n) {
        .el-timeline-item__wrapper {
          transform: translateY(0%);
        }
      }
    }
  }
  :deep(.name-center) {
    .el-timeline-item__node {
      height: 20px;
      border-radius: 4px;
      width: auto;
      padding: 0 5px;
      font-size: 14px;
      font-weight: 500;
      color: #fff;
      .el-timeline-item__icon {
        width: inherit;
        height: inherit;
        line-height: 20px;
      }
    }
  }
}
</style>

记录一下。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值