vue写单条横向时间线

本文介绍了一个使用Vue、CSS和JS手动创建的单条横向时间线组件。组件实现了点击按钮动态生成时间线节点,并根据点击节点显示对应内容的功能。博主分享了代码实现过程,包括HTML结构、CSS样式和JS逻辑,并表达了对于数据处理和样式优化的探讨意愿。
摘要由CSDN通过智能技术生成

vue单条横向时间线(css+js)

我这段时间遇到一个新的需求,在首页做一个时间线的展示图,因为其他的图都是用Echarts写的,这条时间线我也准备用Echarts,找了半天,没找到相关图例,因此,我在这方面纠结了很久,最后没有办法,只能自己手写一个时间线的图,样式很丑,这个就不用在意了,主要的是功能。

先上图吧

这个是基础逻辑就是点击右侧的天蓝色按钮,然后左侧下方的时间线会根据日期的数量动态生成,然后点击下面时间线的中心小圆点,上方的内容会跟着日期的不同而显示对应的内容。首先默认显示的是右侧第一条的日期和左侧下方时间条的第一个日期内容。
在这里插入图片描述
在这里插入图片描述
图片上的数据都是假数据,这些内容应该无所谓了吧

代码如下:

html代码

<div class="chart-content">
              <div id="indexChart3">
                <div class="con-middle-left">
                  <div class="projectCon">
                    <ul class="projectCon-left">
                      <span class="pament">基础合同付款条件:</span>
                      <li
                        v-for="contractTermData in contractTermList"
                        :key="contractTermData.termDesc"
                      >
                        {{
                          contractTermData.termDesc
                        }}&nbsp;&nbsp;&nbsp;&nbsp;<span>{{
                          contractTermData.isDelivered ? "已交付" : "未交付"
                        }}</span>
                      </li>
                    </ul>
                    <div class="projectCon-right" >
                      <div class="pament-con">爱奇艺付款节点:</div>
                      <div >爱奇艺付款节点:{{contractPament.paymentTerm}}&nbsp;&nbsp;&nbsp;&nbsp;<span class="pament-btn">{{
                        contractPament.isPayment ? "已付款" : "未付款"
                      }}</span></div>
                     
                    </div>
                  </div>

                  <!-- 线 -->
                  <div class="line-botton">
                    <div
                      class="line-botton-one"
                      v-for="progressTime in progressTimeList"
                      :key="progressTime.seq"
                      @click="proConClick(progressTime)"
                    >
                      <div class="line-left"></div>
                      <div class="line-middle"></div>
                      <div class="line-left"></div>
                    </div>
                  </div>

                  <!-- 线的数据 -->
                  <div class="data-botton">
                    <div
                      v-for="progressTime in progressTimeList"
                      :key="progressTime.noteDesc"
                      :title="progressTime.noteDesc"
                    >
                      {{ progressTime.finalDeliveryDa }}<br />{{
                        progressTime.noteDesc
                      }}
                    </div>
                  </div>
                </div>

                <!-- 右侧按钮 -->
                <div class="con-middle-right">
                  <ul>
                    <li
                      v-for="projectNameData in projectDate"
                      :key="projectNameData.projectName"
                      @click="projectClick(projectNameData)"
                    >
                      <button :title="projectNameData.projectName" :class='btnclass'>
                        {{ projectNameData.projectName }}
                      </button>
                    </li>
                  </ul>
                </div>
              </div>
            </div>
          </div>

css代码:

.content-left {
  .item-flex {
    display: flex;
    justify-content: center;
    align-items: center;
  }
}
.btnclass{
  background: rgba(248, 192, 66, 0.33);
}
.projectCon {
  width: 500px;
  height: 160px;
  margin: 30px 10px 0 10px;
  border: 1px solid #fff;
  border-radius: 10px;
  overflow-y: auto;
  background:rgb(255, 236, 193);
  color: rgb(68, 61, 61);
  opacity: 1;
  .projectCon-left {
    min-height:100%;
    padding: 20px 10px 10px 10px;
    float: left;
    width:70%;
    border-right:1px solid #ccc;
    .pament{
      width: 48%;
      position: absolute;
      top: 31px;
      padding: 10px 0 0 0;
      background:rgb(255, 236, 193);
        color: red;
    }
    li {
      margin:20px 0  5px 0 ;
      span {
        color: red;
      }
    }
  }
  .projectCon-right{
    padding: 35px 10px 10px 10px;
    float: right;
    width:30%;
    height:100%;
    .pament-con{
      width: 20%;
      position: absolute;
      top: 31px;
      padding: 10px 0 0 0;
      background:rgb(255, 236, 193);
        color: red;
    }
    .pament-btn {
        color: red;
      }
  }
}
.line-botton {
  width: 500px;
  height: 20px;
  margin: 0 10px 0 10px;
  // background: #000;
  display: flex;
  justify-content: center;
  align-items: center;
  .line-botton-one {
    width: 20%;
    display: flex;
    justify-content: center;
    align-items: center;
    .line-left {
      width: 48%;
      border-bottom: 2px solid rgb(46, 212, 96);
      margin-top: 15px;
    }
    .line-middle {
      cursor: pointer;
      border: 1px solid rgb(46, 212, 96);
      width: 10px;
      height: 10px;
      margin-top: 15px;
      border-radius: 50%;
      background: rgb(46, 212, 96);
    }
  }
}
.data-botton {
  width: 500px;
  height: 20px;
  margin: 15px 20px 0 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  div {
    width: 110px;
    height: 40px;
    margin: 0 13px;
    width: 12%;
    text-align: center;
    font-size: 12px;
    overflow: hidden;
    white-space: nowrap;
  }
}
#indexChart3{
  display: flex;
}
.con-middle-left {
  margin-left: 20px;
  width: 85%;
  height: 250px;
}
.con-middle-right {
  margin: 20px 0 0 0;
  width: 15%;
  height: 200px;
  button {
    width: 80px;
    // height: 20px;
    margin-top: 5px;
    padding: 5px 3px 5px 3px ;
    // border: rgb(154, 247, 242) 1px solid;
    border:#fff;
    border-radius: 5px;
    background: #3f75d4;
    font-size: 12px;
    white-space: nowrap;
    overflow: hidden;
    color: #fff;
  }
  button:hover{
    background:#fc544b;
  }
}

js代码:

methods: {
loadStoreData() {
      var self = this;
      var projectDate = {}; //单个项目
      var handleResult = function (res) {
        var data = [];
        var result = 0;
        for (let j = 0; j < res.data.length; j++) {
          projectDate = res.data[j];
          let projectName = projectDate.projectName; //项目名称
          self.exProjectDate.push(projectDate);
          self.projectDate = self.exProjectDate.slice(-7);
        }
        self.progressTimeList = self.projectDate[0].progressList;
        self.contractTermList = self.progressTimeList[0].contractTermList;
        self.contractPament = self.progressTimeList[0]//第一次进页面给时间线的默认值
      };

      var params = {
        object: {
          projectCode: ***,//请求接口需要的参数
        },
      };
      return new Promise((resolve, reject) => {
        api
          .***(params)//这是请求的接口
          .then((response) => {
            if (response.body.code == "0000") {
              let result = response.body;
              if (result) {
                handleResult(result);
              }
            }
          })
          .catch((error) => {
            reject(error);
          });
      });
},
 // 获取展示框数据
    proConClick(progressTimeList) {
      return new Promise((resolve, reject) => {
        this.contractPament = progressTimeList
        this.contractTermList = progressTimeList.contractTermList;
      });
    },

    // 获取时间线日期和内容数据
    projectClick(project) {
      return new Promise((resolve, reject) => {
        this.progressTimeList = [];
        var self = this;
        for (let i = 0; i < project.progressList.length; i++) {
          var progressTimeList = project.progressList[i];
          self.progressTimeList.push(progressTimeList);
        }
        self.contractTermList = self.progressTimeList[0].contractTermList;
        self.contractPament = self.progressTimeList[0]//点击右侧按钮后展示框显示的默认值
      });
    },
},

mounted() {
    this.$nextTick(function () {
      setTimeout(() => {
        this.loadSendData();
      }, 1000);
    });//进入页面自动执行
  },

因为这是用vue写的,所以这些代码是vue的代码,这些样式都不是难点,主要的是这个数据处理,我这个接口返回的数据嵌套了五层,我用的是传参的方式,将获取的数据处理后通过参数传给proConClick和projectClick这两个函数,我也是一个前端小白,如果有什么更好的方法,不管是样式还是数据处理,都非常欢迎大佬们批评指正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值