VUE2中做一个类似于jQuery拖动时间轴的组件

jQuery拖动时间轴的演示地址

https://www.jq22.com/yanshi20974

此处是我已经实现了的全部功能,诸君直接可以用,但是会有一个非常严重的性能问题要和诸君提前说一下。
在JQ的演示中不管创建多少个滑块浏览器都不会掉帧,滑动也非常顺畅,但是在vue项目中当滑块变多后会导致浏览器严重的掉帧问题,CPU占用率也会飙升,初步判断是因为vue是用数据驱动虚拟DOM而我其中是的操作是大量的DOM操作导致的,如果诸君在使用过程中改善了其性能请留言分享,在下感激不尽。
话不多说,上代码。类似$t(“xxx.xxx”)这种国际化的替换成中文即可

vue做的拖拽时间轴组件

2023-5-4 在原有的基础上把一些接口,国际化,都注释了下。
i-class 中的背景小图块需要自己找个素材替代修改即可

<template>
  <div class="time" onselectstart="return false">

    <div v-loading="btnLoading">
      <div class="title-box">
        <span>类型</span>
        <el-select
          v-model="typeVal"
          @change="onSelect"
          placeholder="请选择存储计划周期类型"
          size="small"
          class="w200 title"
        >
          <el-option
            v-for="dict in sys_cycle_type"
            :key="dict.value"
            :label="dict.label"
            :value="parseInt(dict.value)"
          />
        </el-select>

        <el-button slot="reference" class="title-class" type="text" icon="el-icon-delete" @click="deleteAllFun">删除所有</el-button>
      </div>
      
      <div class="df">
        <div>
          <!-- 整个时间功能 -->
          <div
            class="cycle-box"
            v-for="week of weekList"
            :key="week.code"
            @mouseenter="copyMouseenter(week.title)"
          >

            <!-- 周几 -->
            <span class="week">{{ week.title }}</span>

            <div class="slide-list">
              <!-- 时间刻度 -->
              <div class="slide-ruler">
                <div class="scale" v-for="time of timeList" :key="time">{{ time }}</div>
              </div>

              <!-- 时间功能数组中控制周几是否能创建数据disabled -->
              <div
                :style=" week.disabled ? 'background:#C0C8D9;cursor:not-allowed;' : '' "
                class="slide-box"
                @mousedown.stop="fatherMousedown($event, week.code, week)"
              >
                <!-- 初始化的domObj,宽度不等于0并且week.code == code才显示 -->
                <div
                  v-show="domObj.width != 0 && week.code == code"
                  class="item"
                  :style="`width: ${domObj.width}px; left: ${domObj.left}px; background: ${domObj.bg}`"
                ></div>

                <!-- 创建的时间块数组domArr -->
                <div
                  v-for="(item, key) of week.domArr"
                  :key="key"
                  class="item"
                  :style="`width: ${item.width}px; left: ${item.left}px; background: ${item.bg}`"
                  @mousedown.stop="itemMousedown($event, key, item, week.domArr)"
                  @click="timeBlock(week.code, key, item)"
                >
                  <i v-show="item.changeTimeShow && iShow === key" class="i-left-class i-class" @mousedown.stop="checkI('left', $event, code, key, item, week.domArr)"></i>
                  <i v-show="item.changeTimeShow && iShow === key" class="i-right-class i-class" @mousedown.stop="checkI('right', $event, code, key, item, week.domArr)"></i>
                  <!-- hover时间展示 -->
                  <div style="position:absolute;top:0;left:0;width:100%;height:100%;" v-show=" blockShow && !item.changeTimeShow">
                    <el-tooltip placement="top">
                      <div style="text-align: center;" slot="content">
                        {{item.startH}}:{{item.startM}} - {{item.endH}}:{{item.endM}}
                      </div>
                      <div class="timeHover"></div>
                    </el-tooltip>
                  </div>
                  
                  <!-- 点击时间调整 -->
                  <el-popover placement="top" trigger="manual" v-model="item.changeTimeShow" @show="showFun(item)" @hide="hideFun(item)" >
                    <div style="text-align: center;">
                      <div>
                        <el-select
                          v-model="sonVal"
                          placeholder="请选择存储计划周期类型"
                          size="mini"
                          class="w200"
                        >
                          <el-option
                            v-for="dict in options"
                            :key="dict.value"
                            :label="dict.label"
                            :value="dict.value"
                          />
                        </el-select>
                      </div>
                      <div style="margin: 15px 0;">
                        <input size="mini" class="w40" v-model="item.startH" maxlength="2" @input="hhInput('startH', week.code, key, item)"  />
                        <span style="padding: 0 5px;">:</span>
                        <input size="mini" class="w40" v-model="item.startM" maxlength="2" @input="mmInput('startM', week.code, key, item)"  />
                        <span style="padding: 0 5px;">-</span>
                        <input size="mini" class="w40" v-model="item.endH" maxlength="2" @input="hhInput('endH', week.code, key, item)"  />
                        <span style="padding: 0 5px;">:</span>
                        <input size="mini" class="w40" v-model="item.endM" maxlength="2" @input="mmInput('endM', week.code, key, item)"  />
                      </div>
                      <div>
                        <el-button-group>
                          <el-button size="mini" type="primary" @click="btns('delete',week.code, key, item)">删除</el-button>
                          <el-button size="mini" type="primary" @click="btns('cancel',week.code, key, item)">取消</el-button>
                          <el-button size="mini" type="primary" @click="btns('ok',week.code, key, item)">确定</el-button>
                        </el-button-group>
                      </div>
                    </div>
                    <div slot="reference" class="timeHover" ></div>
                  </el-popover>
                  
                  
                </div>
              </div>
            </div>

            <!-- 复制相关 -->
            <div v-show="!week.disabled && week.title == codeHover " class="title-class">
              <el-popover
                placement="left-end"
                width="320"
                v-model="week.copyShow"
                :open-delay="0"
                :close-delay="0">
                <div>
                  <div class="df copy-class mb10">
                    <span>复制到...</span>
                    <span><el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox></span>
                  </div>

                  <div  style="margin: 15px 0;">
                    <el-checkbox-group  v-model="checkedCities" @change="handleCheckedCitiesChange">
                      <el-checkbox :disabled="copyValue === city.value" class="checkbox-class" v-for="city in cities" :label="city.value" :key="city.value">{{city.title}}</el-checkbox>
                    </el-checkbox-group>
                  </div>

                  <div>
                    <el-button type="text" size="mini" @click="copyBtn('cancel',week)">取消</el-button>
                    <el-button type="primary" size="mini" @click="copyBtn('confirm',week)">确定</el-button>
                  </div>
                </div>
                <i style="font-size:16px;" slot="reference" class="el-icon-document-copy" @click="copyBtn('icon',week)" ></i>
              </el-popover>
            </div>

          </div>
        </div>

        <div style="margin-left:20px;">
          <div class="df color-class" >
            <span class="color-bg" style="background:#637DEC;"></span>
            <span>定时</span>
          </div>
          <div class="df color-class" >
            <span class="color-bg" style=";background:#74B557;"></span>
            <span>移动侦测</span>
          </div>
          <div class="df color-class" >
            <span class="color-bg" style="background:#B83F42;"></span>
            <span>报警</span>
          </div>
          <div class="df color-class" >
            <span class="color-bg" style="background:#E58805;"></span>
            <span>动测或报警</span>
          </div>
          <div class="df color-class" >
            <span class="color-bg" style="background:#B9E2FE;"></span>
            <span>动测和报警</span>
          </div>
          <div class="df color-class" >
            <span class="color-bg" style="background:#AA6FFE;"></span>
            <span>事件</span>
          </div>
        </div>
        

      </div>
    </div>
    

    <div class="rbtn">
      <el-button @click="returnCancel">取消</el-button>
      <el-button type="primary" :loading="btnLoading" @click="submit">确定</el-button>
    </div>
    
  </div>
</template>

<script>
// import { listStorageCycle, delStorageCycle, addStorageCycle } from "@/api/storage/storageCycle";
export default {
  props: {
    // 周几能操作
    dayData: {
      type: Array,
      default() {
        return [1,2,3,4,5,6,7]
      },
    },
    id:{
      type: Number,
      default() {
        return 0
      }
    }
  },
  data() {
    return {
      sys_cycle_type: [
        {value:'1',label:'定时'},
        {value:'2',label:'移动侦测'},
        {value:'3',label:'报警'},
        {value:'4',label:'动测或报警'},
        {value:'5',label:'动测和报警'},
        {value:'6',label:'事件'},
      ],
      btnLoading: false,
      // 删除的id,只有要传[]时才调用
      deleteId:[],
    
      // 下拉框所有数据
      options: [
        { label: "定时", value: 1 },
        { label: "移动侦测", value: 2 },
        { label: "报警", value: 3 },
        { label: "动测或报警", value: 4 },
        { label: "动测和报警", value: 5 },
        { label: "事件", value: 6 },
      ],
      // 下拉框选中的数据
      typeVal: 1,
      // 删除所有数据
      deleteAll: false,

      // 核心数据
      // 刻度
      timeList: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24],
      // 所有数据
      weekList: [],
      // 声明的DOM对象
      domObj: {},
      // 控制能做几个时间块
      allNum: 8,
      // 所有数据的code值
      code: 0,
      // 所有数据内domArr的下标值
      key: null,
      timeVal: null,
      // 存根数据
      stubData: {},
      // 是否是选中的时间子块
      loop: 0,
      // 子块的hover是否显示
      blockShow:true,
      // 左右i的显示
      iShow: null,
      // 每个子块的下拉框
      sonVal: null,
      // 小弹框显示前的存根数据,防止修改了时间不点击按钮组直接点空取消弹框而导致时间bug问题
      popoverStubData: [],

      // 复制相关
      // 控制是否显示复制
      copyShow: false,
      codeHover: null,
      checkAll: false,
      checkedCities: [],
      cities: [
        {title:'星期一', value: 0},
        {title:'星期二', value: 1},
        {title:'星期三', value: 2},
        {title:'星期四', value: 3},
        {title:'星期五', value: 4},
        {title:'星期六', value: 5},
        {title:'星期七', value: 6},
      ],
      isIndeterminate: false,
      copyValue: null,
      
    };
  },
  created() {
    this.init()
  },
  mounted() {
    this.listStorageCycle()
  },
  methods: {
    // 初始化数据
    init(){
      this.domObj = {
        width: 0,   //宽度
        left: 0,    //左偏移量
        bg: "#637DEC",    //背景色(与背景值关联,对应着下拉框的值
        value: 1,   //背景值(与背景色关联,对应着下拉框的值
        startH: 0,   //开始时间(时
        startM: 0,   //开始时间(分
        endH: 0,   //结束时间(时
        endM: 0,   //结束时间(分
        changeTimeShow: false,  //控制时间显示与时间调整
      }
      this.weekList = [
        { title: "星期一", code: 0, copyShow: false, domArr: [], disabled: !this.dayData.includes(1) },
        { title: "星期二", code: 1, copyShow: false, domArr: [], disabled: !this.dayData.includes(2) },
        { title: "星期三", code: 2, copyShow: false, domArr: [], disabled: !this.dayData.includes(3) },
        { title: "星期四", code: 3, copyShow: false, domArr: [], disabled: !this.dayData.includes(4) },
        { title: "星期五", code: 4, copyShow: false, domArr: [], disabled: !this.dayData.includes(5) },
        { title: "星期六", code: 5, copyShow: false, domArr: [], disabled: !this.dayData.includes(6) },
        { title: "星期七", code: 6, copyShow: false, domArr: [], disabled: !this.dayData.includes(7) },
      ]
    },
    // 下拉框选择
    onSelect(code) {
      this.domObj = {
        width: 0,   //宽度
        left: 0,    //左偏移量
        value: code,    //背景值(与背景色关联,对应着下拉框的值
        startH: 0,   //开始时间(时
        startM: 0,   //开始时间(分
        endH: 0,   //结束时间(时
        endM: 0,   //结束时间(分
        changeTimeShow: false,
      };
      if (code == 1) {
        this.domObj.bg = "#637DEC";
      } else if (code == 2) {
        this.domObj.bg = "#74B557";
      } else if (code == 3) {
        this.domObj.bg = "#B83F42";
      } else if (code == 4) {
        this.domObj.bg = "#E58805";
      } else if (code == 5) {
        this.domObj.bg = "#B9E2FE";
      } else if (code == 6) {
        this.domObj.bg = "#AA6FFE";
      }
    },
    // 删除所有数据
    deleteAllFun() {
      this.deleteAll = false
      this.init();
    },
    // 拷贝按钮
    copyBtn(type,val) {
      this.checkAll = false;
      if(type === 'icon'){
        this.copyValue = val.code
        this.checkedCities = []
        this.checkedCities.push(this.copyValue)
      }else if(type === 'confirm'){
        if(this.checkedCities.length !== 1){
          let arr = JSON.parse(JSON.stringify(val.domArr))
          arr.forEach( j => {
            j.changeTimeShow = false
          })
          this.checkedCities.forEach( i => {
            if(i != val.code){
              this.weekList[i].domArr = JSON.parse(JSON.stringify(arr))
            }
          })
        }
        val.copyShow = false
        this.copyValue = null
        this.checkedCities = []
      }else if(type === 'cancel'){
        val.copyShow = false
        this.copyValue = null
        this.checkedCities = []
      }
    },
    // 进入周几事件后的拷贝功能
    copyMouseenter(title) {
      this.codeHover = title
    },
    // 复制到...全选
    handleCheckAllChange(val) {
      if(val){
        this.checkedCities = [0,1,2,3,4,5,6]
      }else{
        this.checkedCities = []
        this.checkedCities.push(this.copyValue)
      }
      this.isIndeterminate = false;
    },
    handleCheckedCitiesChange(value) {
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.cities.length;
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.cities.length;
    },
    // 父节点的按下事件
    fatherMousedown(e, code, item) {
      // 控制是否还能创建
      if(item.domArr.length >= this.allNum || item.disabled){
        return false
      }
      this.code = code;
      let op = e.target;
      // 算出鼠标相对元素的位置
      let disX = e.clientX;
      // console.log(e.clientX, op.offsetLeft, "相对位置是他left的值", disX);
      // left
      this.domObj.left = e.layerX;
      // 开始时间
      this.domObj.startH = this.conversionhs('H',this.domObj.left*2);
      this.domObj.startM = this.conversionhs('M',this.domObj.left*2);
      //鼠标移动事件
      document.onmousemove = (e) => {
        //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
        this.domObj.width = e.clientX - disX;
        // 拖动的宽不能大于刻度,否则就等于 刻度-偏移的left = 最终宽
        if(this.domObj.width + this.domObj.left > 720){
          this.domObj.width = 720 - this.domObj.left
        }
        // 结束时间
        this.domObj.endH = this.conversionhs('H',this.domObj.left*2 + this.domObj.width*2);
        this.domObj.endM = this.conversionhs('M',this.domObj.left*2 + this.domObj.width*2);
      };
      // 鼠标抬起事件
      document.onmouseup = (e) => {
        if (this.domObj.width > 0) {
          // console.log('width宽度==》》',this.domObj.width,'----left左偏移==》》',this.domObj.left)
          // console.log(`${this.domObj.startH} : ${this.domObj.startM} - ${this.domObj.endH} : ${this.domObj.endM}`)
          item.domArr.push(this.domObj);
        }
        this.onSelect(this.typeVal);
        document.onmousemove = null;
        document.onmouseup = null;
      };
    },
    // 子块节点的长按
    itemMousedown(e, key, item, arr) {
      this.loop = setTimeout( () => {
        this.loop = 0
        let disX = e.clientX;
        let blockLeft = item.left;//左边偏移量left
        let blockWidth = item.width;//子滑块的宽
        // 控制子块长按时的hover显示
        this.blockShow = false;
        item.changeTimeShow = false
        // console.log('是否显示了按钮组',item.changeTimeShow)
        let arrCopy = JSON.parse(JSON.stringify(arr))
        // 对需要移动的子块的所在数组重新按照left大小排序
        function sortLeft(a,b){
          return a.left - b.left
        }
        arrCopy.sort(sortLeft)
        // 处理左右滑动的范围
        let leftL = 0; // 往左滑动的范围
        let leftR = 720; // 往右滑动的范围
        let mark = 0;
        for(let i=0; i<arrCopy.length; i++){
          if(arrCopy[i].left === item.left){
            mark = i
            break
          }
        }
        if(arrCopy.length === 1){
          leftL = 0; // 往左滑动的范围
          leftR = 720; // 往右滑动的范围
        }else{
          if(mark === 0){
            leftL = 0; // 往左滑动的范围
            leftR = arrCopy[mark +1].left; // 往右滑动的范围
          }else if(mark === arrCopy.length -1){
            leftL = arrCopy[mark-1].left + arrCopy[mark-1].width
            leftR = 720
          }else if(mark !== 0 && mark < arrCopy.length-1){
            leftL = arrCopy[mark-1].left + arrCopy[mark -1].width
            leftR = arrCopy[mark+1].left
          }
        }
        // console.log('arrCopy==',arrCopy,'==mark=',mark,'=leftL=',leftL,'=leftR=',leftR)
        // 子块鼠标移动事件
        document.onmousemove = (e) => {
          // console.log(e,'子块滑动事件',e.clientX,'--==--',e.clientX - disX,'---left=',blockLeft + (e.clientX - disX))
          if(blockLeft + (e.clientX - disX) <= leftL){
            item.left = leftL
          }else if(item.width + (blockLeft + (e.clientX - disX)) <= leftR){
            // console.log('总长==',item.width + blockLeft + (e.clientX - disX))
            item.left = blockLeft + (e.clientX - disX)
          }
          // 开始时间
          item.startH = this.conversionhs('H',item.left * 2);
          item.startM = this.conversionhs('M',item.left * 2);
          // 结束时间
          item.endH = this.conversionhs('H',item.left * 2 + item.width*2);
          item.endM = this.conversionhs('M',item.left * 2 + item.width*2);
        };
        // 子块鼠标抬起事件
        document.onmouseup = (e) => {
          this.blockShow = true;
          this.iShow = null
          document.onmousemove = null;
          document.onmouseup = null;
        };
      },200)
      return false;
    },
    // 子块节点的单击
    timeBlock(code, key, item) {
      clearTimeout(this.loop)
      if(this.loop !== 0){
        this.iShow = key
        this.sonVal = item.value
        // console.log('单击=',code, key, JSON.stringify(item) );
        this.stubData = JSON.parse(JSON.stringify(item))
        // 找到对应的节点,根据条件把对应节点打开或者关闭,但是其它节点要全部关闭
        this.weekList.map( (v,i) => {
          v.domArr.map( (val, j) => {
            if(i == code && j == key){
              item.changeTimeShow = !item.changeTimeShow
            }else{
              this.weekList[i].domArr[j].changeTimeShow = false
            }
          })
        })
      }
      return false;
    },
    // 选中的左右小方块
    checkI(type, e, code, key, item, arr) {
      this.loop = setTimeout( () => {
        this.loop = 0
        let disX = e.clientX;
        let blockLeft = item.left;//左边偏移量left
        let blockWidth = item.width;//子滑块的宽
        item.changeTimeShow = false
        item.value = this.stubData.value
        // console.log(item,'--->>>>>',this.stubData)
        // console.log('type==>>点击的那个',type, e, key, item, arr)
        let arrCopy = JSON.parse(JSON.stringify(arr))
        // 对需要移动的子块的所在数组重新按照left大小排序
        function sortLeft(a,b){
          return a.left - b.left
        }
        arrCopy.sort(sortLeft)
        // 处理左右滑动的范围
        let leftL = 0; // 往左滑动的范围
        let leftR = 720; // 往右滑动的范围
        let mark = 0;
        for(let i=0; i<arrCopy.length; i++){
          if(arrCopy[i].left === item.left){
            mark = i
            break
          }
        }
        if(arrCopy.length === 1){
          leftL = 0; // 往左滑动的范围
          leftR = 720; // 往右滑动的范围
        }else{
          if(mark === 0){
            leftL = 0; // 往左滑动的范围
            leftR = arrCopy[mark +1].left; // 往右滑动的范围
          }else if(mark === arrCopy.length -1){
            leftL = arrCopy[mark-1].left + arrCopy[mark-1].width
            leftR = 720
          }else if(mark !== 0 && mark < arrCopy.length-1){
            leftL = arrCopy[mark-1].left + arrCopy[mark -1].width
            leftR = arrCopy[mark+1].left
          }
        }
        // console.log('arrCopy==',arrCopy,'==mark=',mark,'=leftL=',leftL,'=leftR=',leftR)
        // 子块鼠标移动事件
        document.onmousemove = (e) => {
          // console.log(blockWidth,'子块滑动事件',e.clientX,'--==-运算的-',e.clientX - disX,'---left=',blockLeft + (e.clientX - disX))
          if(type === 'left'){
            if(blockLeft + (e.clientX - disX) < leftL){
              item.left = leftL
            }else{
              if(blockWidth - (e.clientX - disX) >= 0){
                item.left = blockLeft + (e.clientX - disX)
                item.width = blockWidth - (e.clientX - disX)
              }
            }
          }else if(type === 'right'){
            if(blockWidth + (blockLeft + (e.clientX - disX)) <= leftR){
              item.width = blockWidth + (e.clientX - disX)
            }
          }
          // 开始时间
          item.startH = this.conversionhs('H',item.left * 2);
          item.startM = this.conversionhs('M',item.left * 2);
          // 结束时间
          item.endH = this.conversionhs('H',item.left * 2 + item.width*2);
          item.endM = this.conversionhs('M',item.left * 2 + item.width*2);
        };
        // 左右小方块的鼠标抬起事件
        document.onmouseup = (e) => {
          this.iShow = null
          if(item.width <= 0){
            this.weekList[code].domArr.splice(key,1)
          }
          document.onmousemove = null;
          document.onmouseup = null;
        };
      },200)
      return false;
    },
    // 分钟 换算 时,分
    conversionhs(type,timeNum) {
      if(type == 'H'){
        return parseInt(timeNum / 60) < 10 ? '0'+parseInt(timeNum / 60) : parseInt(timeNum / 60)
      }else if(type == 'M'){
        return parseInt(timeNum % 60) < 10 ? '0'+parseInt(timeNum % 60) : parseInt(timeNum % 60)
      }
    },
    // 时,分 换算成 px
    conversionpx(type, pxNum){
      if(type == 'left'){
        return (parseInt(pxNum.startH) * 60 + parseInt(pxNum.startM))/2
      }else if(type == 'width'){
        return ((parseInt(pxNum.endH) * 60 + parseInt(pxNum.endM)) - (parseInt(pxNum.startH) * 60 + parseInt(pxNum.startM)))/2
      }
    },
    // 点击时间调整-按钮组
    btns(type, code, key, item) {
      // console.log(type, code, key,JSON.stringify(item));
      // console.log('==1');
      if(type == 'delete'){
        this.weekList[code].domArr.splice(key,1)
      }else if(type == 'cancel'){
        this.weekList[code].domArr[key] = this.stubData
        item.changeTimeShow = false
        this.iShow = null
      }else if(type == 'ok'){
        // console.log('点击ok要执行的操作',item,item.startM)
        item.startH = this.timeVerification(item.startH)
        item.startM = this.timeVerification(item.startM)
        item.endH = this.timeVerification(item.endH)
        item.endM = this.timeVerification(item.endM)
        this.operate(code, item)
      }
    },
    // 颜色调整
    adjustment(val) {
      if (val == 1) {
        return "#637DEC";
      } else if (val == 2) {
        return "#74B557";
      } else if (val == 3) {
        return "#B83F42";
      } else if (val == 4) {
        return "#E58805";
      } else if (val == 5) {
        return "#B9E2FE";
      } else if (val == 6) {
        return "#AA6FFE";
      }
    },
    // 按钮组-确定-验证逻辑
    operate(code, item) {
      // 1-时间验证
      if(parseInt(item.startH) > parseInt(item.endH) || (parseInt(item.startH) == parseInt(item.endH) && parseInt(item.startM) >= parseInt(item.endM))){
        this.$message.warning("开始时间必须早于结束时间");
        return
      }
      // 2-区域变更
      let domArr = this.weekList[code].domArr
      // console.log('查找对应星期的所有时间块数据==',domArr,item)
      let arrCopy = JSON.parse(JSON.stringify(domArr))
      // 对需要移动的子块的所在数组重新按照left大小排序
      function sortLeft(a,b){
        return a.left - b.left
      }
      arrCopy.sort(sortLeft)
      let mark = 0;
      for(let i=0; i<arrCopy.length; i++){
        if(arrCopy[i].left === item.left){
          mark = i
          break
        }
      }
      if(arrCopy.length !== 1){
        if(mark === 0){
          if(`${arrCopy[mark].endH}:${arrCopy[mark].endM}` > `${arrCopy[mark+1].startH}:${arrCopy[mark+1].startM}`){
            this.$message.warning("时间段存在重复,请检查后重新设置");
            return false
          }
        }else if(mark === arrCopy.length -1){
          if(`${arrCopy[mark].startH}:${arrCopy[mark].startM}` < `${arrCopy[mark-1].endH}:${arrCopy[mark-1].endM}`){
            this.$message.warning("时间段存在重复,请检查后重新设置");
            return false
          }
        }else if(mark !== 0 && mark < arrCopy.length -1){
          if(`${arrCopy[mark].startH}:${arrCopy[mark].startM}` < `${arrCopy[mark-1].endH}:${arrCopy[mark-1].endM}`
          ||
          `${arrCopy[mark].endH}:${arrCopy[mark].endM}` > `${arrCopy[mark+1].startH}:${arrCopy[mark+1].startM}`){
            // 修改的开始时间要 大于等于 之前的结束时间 或 修改的结束时间 小于等于 之后的 开始时间
            this.$message.warning("时间段存在重复,请检查后重新设置");
            return false
          }
        }
      }
      item.left = this.conversionpx('left',item)
      item.width = this.conversionpx('width',item)
      item.changeTimeShow = !item.changeTimeShow
      item.value = this.sonVal
      item.bg = this.adjustment(item.value)
      this.iShow = null
    },
    // 小弹框显示时触发
    showFun(item) {
      this.popoverStubData.push(JSON.parse(JSON.stringify(item)))
    },
    // 小弹框隐藏时触发
    hideFun(item) {
      if(this.iShow != null){
        item.endH = this.popoverStubData[0].endH
        item.endM = this.popoverStubData[0].endM
        item.startH = this.popoverStubData[0].startH
        item.startM = this.popoverStubData[0].startM
      }
      this.popoverStubData.splice(0,1)
    },
    // 剥离自定义指令的小时事件
    hhInput(val, code, key, item){
      var reg = RegExp(/\D/);
      if( reg.test(item[val]) ){
        item[val] = '00'
      }else if( item[val] >= 24 ){
        item[val] = 24
        if(item[val] == 24 ){
          item[val == 'startH' ? 'startM' : 'endM'] = '00'
        }
      }
    },
    // 剥离自定义指令的分钟事件
    mmInput(val, code, key, item){
      var reg = RegExp(/\D/);
      // 数字验证
      if( reg.test(item[val]) || item['startH'] == 24 || item['endH'] == 24 ){
        item[val] = '00'
      }else if( item[val] > 59 ){
        item[val] = 59
      }
    },
    // 点击确定后验证时间数据是否需要添加 '0' 或者 '00' 或者不变
    timeVerification(time) {
      let timeData = time.toString()
      if(timeData.length == 0){
        return '00'
      }else if(timeData.length == 1){
        return `0${timeData}`
      }else if(timeData.length == 2){
        return timeData
      }
    },
    // 取消
    returnCancel() {
      this.$emit('returnCancel')
    },
    // 确定
    submit() {
      // this.$emit('returnSubmit')
      // console.log(this.domObj,'---===storagePlanId=',this.id,"查看data内的数据==>>", JSON.stringify(this.weekList));
      this.addStorageCycle()
    },
    // 查询
    listStorageCycle() {
      this.btnLoading = false
      // listStorageCycle({storagePlanId:this.id}).then( res => {
      //   if(res.code === 200 && res.rows.length != 0){
      //     // 此处如果接口正常并且有数据才能进行操作
      //     res.rows.forEach( i => {
      //       this.deleteId.push(i.storageTimeId)
      //       this.weekList.forEach( j => {
      //         if(i.week - 1 == j.code){
      //           let obj = {
      //             width: i.width,   //宽度
      //             left: i.left,    //左偏移量
      //             bg: this.adjustment(i.type),    //背景色(与背景值关联,对应着下拉框的值
      //             value: i.type,   //背景值(与背景色关联,对应着下拉框的值
      //             startH: i.startTime.split(':')[0],   //开始时间(时
      //             startM: i.startTime.split(':')[1],   //开始时间(分
      //             endH: i.endTime.split(':')[0],   //结束时间(时
      //             endM: i.endTime.split(':')[1],   //结束时间(分
      //             changeTimeShow: false,  //控制时间显示与时间调整
      //           }
      //           j.domArr.push(obj)
      //         }
      //       })
      //     })
      //     // console.log(this.deleteId,'《==删除的id=====渲染的数据==》',JSON.stringify(this.weekList))
      //   }else if(res.code != 200){
      //     this.$message.warning(res.msg);
      //   }
      //   this.btnLoading = false
      // })
    },
    // 新增或修改
    addStorageCycle(){
      this.btnLoading = true;
      // 数据处理
      let params = []
      this.weekList.forEach( i => {
        i.domArr.forEach( j => {
          if(j){
            let obj = {
              startTime: `${j.startH}:${j.startM}`,  //存储开始时间 HH:MM
              endTime: `${j.endH}:${j.endM}`,  //存储结束时间 HH:MM
              storagePlanId: this.id,  //存储计划id
              type: j.value,  //存储计划周期类型(1=定时 2=移动侦测 3=报警 4=动测或报警 5=动测和报警 6=事件)
              week: i.code + 1,  //星期(1~7)
              width: j.width, //宽
              left: j.left,  //left
            }
            params.push(obj)
          }
        })
      })
      // console.log('接口参数==>>',params)
      if(this.deleteId.length === 0 && params.length === 0){
        this.$emit('returnSubmit')
        this.btnLoading = false;
        return
      }
      if(params.length != 0){
        addStorageCycle(params).then( res => {
          // console.log('新增或者修改返回==>',res)
          if( res.code == 200){
            this.$message.warning('成功');
            this.$emit('returnSubmit')
          }else{
            this.$message.warning('失败');
          }
          this.btnLoading = false
        })
      }else{
        this.delStorageCycle()
      }
    },
    // 当要传的数据是[]时则调用(删除所有)
    delStorageCycle(){
      delStorageCycle(this.deleteId).then( res => {
        if( res.code == 200){
          this.$message.warning('成功');
          this.$emit('returnSubmit')
        }else{
          this.$message.warning('失败');
        }
        this.btnLoading = false
      })
    },
    
  },
};
</script>
<style lang="scss" scoped>
.title-box {
  margin-bottom: 20px;
}
.title-class {
  margin-left: 10px;
}
.cycle-box {
  margin: 15px 0;
  width: 810px;
  display: flex;
  align-items: end;
}
.week {
  // color: #fff;
  padding-right: 10px;
}
/* 此处总长是720,是一天1440分钟的一半 */
.slide-list {
  width: 720px;
  // color: #fff;
}
.slide-ruler {
  position: relative;
  left: -5px;
  width: 730px;
  display: flex;
  justify-content: space-between;
}
.scale {
  text-align: center;
  width: 15px;
  font-size: 12px;
}
.slide-box {
  width: 100%;
  height: 20px;
  background: #000;
  display: flex;
  position: relative;
}
.item {
  height: 100%;
  position: absolute;
}
.i-class{
  width: 6px;
  height: 20px;
  position: absolute;
  display: inline-block;
  background: url(../../../assets/image/xiaofk.png);
  background-position: -5px;
  z-index: 1;
}
.i-left-class{
  left: -3px;
}
.i-right-class{
  right: -3px;
}
.i-class:hover{
  cursor:w-resize
}

.timeHover {
  width: 100%;
  height: 100%;
  display: inline-block;
}
.copy-class{
  justify-content: space-between;
  border-bottom: 1px solid #EEEEEE;
}
.checkbox-class{
  margin: 5px 10px;
}
.w40{
  width: 40px !important;
}
.color-class{
  align-items: center;
  margin-bottom:10px;
}
.color-bg{
  width:20px;
  height:20px;
  margin-right:10px;
}
.df{
  display: flex;
}
</style>
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐