vue项目使用纯js封装时间轴

特定需求自定义时间轴


在这里插入图片描述

主页面index.vue

在一个主页面index.vue里面调用这个时间轴和日历以及刚特图组件

<!-- 日期  &&  时间选择器 -->
<el-row class="meeting-select-datatime">
  <!-- 时间轴组件 -->
  <timeline @chosenTime="selectTimeline(arguments)" />  //接收时间轴的数据
  <!-- 日期选择器部分 -->
  <CalendarGanttChart :time-data="timeData" />   //把获取到的数据传给日历组件
</el-row>
js:
//获取到选择的时间日期
selectTimeline(val){
    this.timeData=[];
    this.timeData.push(val[0]);
    this.timeData.push(val[1]);
    this.timeData.push(val[2]);
},

实现思路

用js初始化时间,使用new Date,再用获取到的当天日期来计算前15天以及后15天的所有日期,一定要注意时间的准确性
再就是左右点击,为前一天,后一天

<template>
  <div class="meeting-timeline">
    <div class="timeline-line">
      <div
        class="left-next"
        @click="chosenTimePerform(chosenTime,'leftNext')"
      />
      <div
        class="right-next"
        @click="chosenTimePerform(chosenTime,'rightNext')"
      />
      <div class="timeline-time-class">
        <span
          v-for="time in timelineListPop"
        >
          <span
            v-show="time.getDate()===1"
            class="time-month"
          >
            <span>{{ time.getMonth()===0? '1':time.getMonth()+1 }}月</span>
          </span>
          <span
            class="time-notoday"
            @click="chosenTimePerform(time)"
          >{{ time.getDate() }}</span>
        </span>
        <span
          class="time-today"
          @click="chosenTimePerform(chosenTime)"
        >{{ chosenTime.getDate() }}</span>
        <span
          v-for="time1 in timelineListPush"
        >
          <span
            v-show="time1.getDate()===1"
            class="time-month"
          >
            <span>{{ time1.getMonth()+1 }}月</span>
          </span>
          <span
            class="time-notoday"
            @click="chosenTimePerform(time1)"
          >{{ time1.getDate() }}</span>
        </span>
      </div>
      <el-date-picker
        v-model="chosenTime"
        type="date"
        placeholder="选择日期"
        :clearable="false"
        prefix-icon="icon-rili"
        @change="chosenTimePerform(chosenTime)"
      />
    </div>
  </div>
</template>


<script>
import "@/views/my-meeting/css/myMeet.scss";
import {formatTime} from '@/utils';
export default {
    name: "Timeline",
    props:{


    },
    data(){
        return{
            //时间日期轴
            chosenTime:'',
            timelineListPop:[],
            timelineListPush:[],
        }
    },
    watch:{
        '$store.state.account.user.companyId':function () {
            this.timelineData();
        },
    },
    created() {
        this.timelineData();
    },
    methods:{
        //组装时间轴数据
        timelineData(){
            let nowDate = new Date();
            let fullYear = nowDate.getFullYear();
            let month = nowDate.getMonth(); // getMonth 方法返回 0-11,代表1-12月
            let day = nowDate.getDate(); //获取当日
            this.chosenTime=new Date(fullYear, month, day);  //初始化选择日期为当天
            this.GetDateStr(this.chosenTime,-15,15);
        },
        //获取当前时间前后N天前后日期的方法
        GetDateStr(chosenTime,AddDayPop,AddDayPush) {
            let base = new Date(chosenTime).getTime()
            let oneDay = 24 * 3600 * 1000;
            let date = [];
            let data = [Math.random() * 300];
            for (let i = -1; i >=AddDayPop; i--) {
                let now = new Date(base -= oneDay);
                date.push(new Date(now.getFullYear(), now.getMonth(), now.getDate()));
                data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
            }
            let newdate = date.reverse()   //用于颠倒元素
            this.timelineListPop=newdate;  //时间轴前15天日期


            let basePush = new Date(chosenTime).getTime()
            let oneDayPush = 24 * 3600 * 1000;
            let datePush = [];
            let dataPush = [Math.random() * 300];
            for (let n = 1; n <=AddDayPush; n++) {
                let now1 = new Date(basePush += oneDayPush);
                datePush.push(new Date(now1.getFullYear(), now1.getMonth(), now1.getDate()));
                dataPush.push(Math.round((Math.random() - 0.5) * 20 + dataPush[n - 1]));
            }
            this.timelineListPush=datePush;  //时间轴后15天日期
            //初始化组件传参给日历
            this.$emit('chosenTime',chosenTime,this.timelineListPop,this.timelineListPush)
        },
        //  选择日期
        chosenTimePerform(time,state){
            if(state!==undefined&&state==='leftNext'){
                let data=new Date(time.getFullYear(),time.getMonth(),time.getDate()-1);
                this.GetDateStr(data,-15,15);
                this.chosenTime=data;  //选择日期
            }else if(state!==undefined&&state==='rightNext'){
                let data=new Date(time.getFullYear(),time.getMonth(),time.getDate()+1);
                this.GetDateStr(data,-15,15);
                this.chosenTime=data;  //选择日期
            }else{
                this.GetDateStr(time,-15,15);
                this.chosenTime=time;  //选择日期
            }
            this.$emit('chosenTime',this.chosenTime,this.timelineListPop,this.timelineListPush)
        }
    }
}
</script>


<style scoped lang="scss">
::v-deep .el-date-editor.el-input, .el-date-editor.el-input__inner{
  width: 40px;
  position: relative;
  left: calc(100% - -8px);
  bottom: 36px;
}
::v-deep .el-input--prefix .el-input__inner{
  border: none;
}
::v-deep .el-input__icon{
  font-size: 30px;
}
</style>

主要css

.meeting-timeline{
  width: calc(100% - 70px);
  height: 3%;
  margin-top: 40px;
  margin-left: 14px;
  .timeline-line{
    background: -webkit-linear-gradient(left, #fff -4%, rgba(188, 188, 188, 0.30) 50%,#fff 100%);
    height: 12px;
  }
  .timeline-time-class{
    display: flex;
    justify-content: space-around;
  }
  .time-month{
    position: absolute;
    top: 14px;
    color: #CCCCCC;
    font-size: 18px;
  }
  .time-notoday{
    color: #BCBCBC;
    line-height: 16px;
    font-size: 18px;
    &:hover{
      background: #0066CC;
      border-radius: 6px;
      color: #ffffff;
      position: relative;
    }
  }
  .time-today{
    display: flex;
    justify-content: center;
    font-size: 18px;
    color: #ffffff;
    width: 30px;
    height: 36px;
    background: #0066CC;
    border-radius: 6px;
    margin-top: -10px;
    align-items:center;
  }
  //两侧下一个日期
  .left-next{
    width: 0px;
    height: 0px;
    border-top: 10px solid transparent;
    border-right: 10px solid;
    border-bottom: 10px solid transparent;
    position: absolute;
    left: 60px;
    border-right-color: #0066CC;
    cursor: pointer;
  }
  .right-next{
    width: 0px;
    height: 0px;
    border-top: 10px solid transparent;
    border-left: 10px solid;
    border-bottom: 10px solid transparent;
    position: absolute;
    border-left-color: #0066CC;
    right: 100px;
    cursor: pointer;
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值