The date progress component supports drag and drop to edit the date progress (see picture, source code attached)

See the picture for the effect. For the "component" you just wrote, you can write the parameters that need to be stripped into props. If you don't know it, you can improve it yourself. If you don't understand it, you can ask the group. Generally, you won't answer.

 When dragging, the time and proportion will change by itself. If you need to get the source code yourself, just refer to the idea of ​​non-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);
      }
    }
  }
}

 

Guess you like

Origin blog.csdn.net/dkr380205984/article/details/105066266