日期进度组件支持拖拽编辑日期进度(看图,附源码)

效果看图,刚写的“组件”,需要剥离的参数自己写进props就行,不完善的地方自己完善,有什么不懂的地方可以进群问,一般不会回答

 拖拽的时候时间和比例自己会变,有需要自己拿源码,非vue的参考下思路就行

<template>
  <div class="zhTimeProcess">
    <div class="processCtn"
      :ref="'zhTimeProcess'+ id">
      <div class="processLine"
        v-for="(item,index) in renderData"
        :key="'processLine' + index"
        :style="{'width':item.width + 'px'}">{
   
   {item.percent * 100 + '%'}}({
   
   {item.name}})</div>
      <div class="timeNode unEdit">
        <span class="time">{
   
   {startTime}}</span>
        <!-- <span class="name">下单日期</span> -->
      </div>
      <div class="timeNode"
        @mousedown.left="startDrag($event,item)"
        @mouseup.left="endDrag(item)"
        @mousemove="dragging($event,item,index)"
        @mouseout="endDrag(item)"
        v-for="(item,index) in renderData"
        :key="'timeNode' + index"
        :class="{'unEdit':index===renderData.length-1}"
        :style="{'left':item.left + 'px'}">
        <span class="time">{
   
   {cmpDate(item.percent)}}</span>
        <!-- <span class="name">{
   
   {item.name}}</span> -->
      </div>
    </div>
  </div>
</template>
<script>
import './zhTimeProcess.less'
export default {
  data () {
    return {
      id: 1, // 用于标记当前组件的id,一个页面有多个该组件的时候可以用到
      startTime: '2020-01-01',
      endTime: '2020-03-01',
      needTime: 0, // 所需时间
      testData: [{
        name: '物料计划',
        percent: 0.2
      }, {
        name: '物料入库',
        percent: 0.3
      }, {
        name: '半成品入库',
        percent: 0.4
      }, {
        name: '成品装箱',
        percent: 0.1
      }],
      domWidth: 0,
      renderData: [],
      mousePosition: 0 // 记录鼠标位置
    }
  },
  methods: {
    cmpDate (percent) {
      let startTime = new Date(this.startTime)
      startTime.setDate(startTime.getDate() + Math.round(percent * this.needTime))
      return startTime.getFullYear() + '-' + (startTime.getMonth() < 9 ? '0' + (startTime.getMonth() + 1) : (startTime.getMonth() + 1)) + '-' + (startTime.getDate() < 10 ? '0' + (startTime.getDate()) : startTime.getDate())
    },
    startDrag (ev, item) {
      this.mousePosition = ev.clientX
      item.draggble = true
    },
    endDrag (item) {
      item.draggble = false
    },
    dragging (ev, item, index) {
      if (item.draggble) {
        let itemNext = this.renderData[index + 1]
        let deltX = ev.clientX - this.mousePosition
        item.left = item.left + deltX
        item.width = item.width + deltX
        item.percent = (item.width / this.domWidth).toFixed(2)
        itemNext.width = itemNext.width - deltX
        itemNext.percent = (itemNext.width / this.domWidth).toFixed(2)
        this.mousePosition = ev.clientX
        this.$forceUpdate()
      }
      // console.log(ev)
    }
  },
  mounted () {
    this.needTime = (new Date(this.endTime).getTime() - new Date(this.startTime).getTime()) / 1000 / 60 / 60 / 24
    this.domWidth = this.$refs['zhTimeProcess' + this.id].offsetWidth
    let left = 0
    this.renderData = this.testData.map((item) => {
      item.width = Math.round(this.domWidth * item.percent)
      left = left + item.width
      item.left = left
      return item
    })
  }
}
</script>
.zhTimeProcess{
  display: block;
  height: 20px;
  padding: 25px 0;
  .processCtn{
    height:100%;
    background: #4989D3;
    position: relative;
    .processLine{
      text-align: center;
      display: inline-block;
      height: 100%;
      line-height: 20px;
      font-size: 14px;
      color: #fff;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .timeNode{
      position: absolute;
      width: 2px;
      top: 0;
      bottom: 0;
      background: #fff;
      cursor: pointer;
      &.unEdit{
        background:rgba(0,0,0,0);
        &::after{
          border:0;
        }
        &::before{
          border:0;
        }
      }
      &::after{
        content: '';
        position: absolute;
        width: 0;
        height: 0;
        border:6px solid transparent;
        border-top-color: #4989D3;
        top: -9px;
        left: -5px;
      }
      &::before{
        content: '';
        position: absolute;
        width: 0;
        height: 0;
        border:6px solid transparent;
        border-bottom-color: #4989D3;
        bottom: -9px;
        left: -5px;
      }
      .time{
        position: absolute;
        white-space: nowrap;
        font-size: 12px;
        left: 1px;
        top: -28px;
        transform: translate(-50%);
        color: rgba(0,0,0,0.85);
      }
      .name{
        position: absolute;
        white-space: nowrap;
        font-size: 12px;
        left: 1px;
        bottom: -28px;
        transform: translate(-50%);
        color: rgba(0,0,0,0.85);
      }
    }
  }
}

猜你喜欢

转载自blog.csdn.net/dkr380205984/article/details/105066266