效果图:

图一:

时间线

 图二:

本文用了vue3+ ts+ element-plus。

HTML代码如下:

<template>
  <div class="slider-demo-block">
    <el-slider
      v-model="value2"
      :step="1"
      @change="changeSlider"
      :show-tooltip="false"
      :marks="marks"
      :max="getDaysArr.length - 1"
    />
  </div>
</template>

 

封装组件,后端传递开始时间和结束时间,前端算出中间相差多少天

图一效果:后端只传了一个开始时间和结束时间

<script lang="ts">
import { computed, defineComponent, reactive, ref } from 'vue'
//封装了计算开始时间和结束时间的方法
import * as calculate from './calculatetime'
import type { CSSProperties } from 'vue'
interface Mark {
  style: CSSProperties
  label: string
}
type Marks = Record<string, Mark | string>
export default defineComponent({
  props: {
    startTime: {
      type: String,
      default: '2020-2-12',//默认开始时间
    },
    endTime: {
      type: String,
      default: '2020-3-1',//默认结束时间
    },
  },
  setup(props) {
    const value2 = ref(0)
    const getDaysArr = calculate.getDays(props.startTime, props.endTime)
    //得到开始时间与结束时间相差的天数了
    const getDaysObj = calculate.arrToObj(getDaysArr)
    console.log(getDaysObj, 'getDaysObj')
    const marks = reactive<Marks>(getDaysObj as Marks)
    const changeSlider = (val) => {
    //这里拿到滑动到哪一天
      console.log(getDaysArr[val])
      return getDaysArr[val]
    }
    return {
      getDaysArr,
      value2,
      marks,
      changeSlider,
    }
  },
})
</script>

 

图二效果:后端传了一个时间数组,包含了一段时间(只需要将图一的getDaysArr 的获取时间段的行为改为时间数组;props默认开始时间和默认结束时间改为时间数组的第一位和最后一位即可,以下代码是一个简单的示例)

<script lang="ts">
import { computed, defineComponent, reactive, ref } from 'vue'
//封装了计算开始时间和结束时间的方法
import * as calculate from './calculatetime'
import type { CSSProperties } from 'vue'
interface Mark {
  style: CSSProperties
  label: string
}
type Marks = Record<string, Mark | string>
export default defineComponent({
  props: {
    startTime: {
      type: String,
      default: '0',//默认开始时间
    },
    endTime: {
      type: String,
      default: '7200',//默认结束时间
    },
  },
  setup(props) {
    const value2 = ref(0)
    const getDaysArr = ['0','3600','7200']//此处为时间数组,就不需要使用封装的计算时间的方法了
    //得到开始时间与结束时间相差的天数了
    const getDaysObj = calculate.arrToObj(getDaysArr)
    console.log(getDaysObj, 'getDaysObj')
    const marks = reactive<Marks>(getDaysObj as Marks)
    const changeSlider = (val) => {
    //这里拿到滑动到哪一天
      console.log(getDaysArr[val])
      return getDaysArr[val]
    }
    return {
      getDaysArr,
      value2,
      marks,
      changeSlider,
    }
  },
})
</script>

封装计算开始时间与结束时间之间的天数,以及数组转对象的方法

新建calculatetime方法文件,写入以下代码

/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
// 获取间隔天数
export function getDays(day1, day2) {
  // 获取入参字符串形式日期的Date型日期
  let st = day1.getDate()
  const et = day2.getDate()

  const retArr = []

  // 获取开始日期的年,月,日
  let yyyy = st.getFullYear(),
    mm = st.getMonth(),
    dd = st.getDate()

  // 循环
  while (st.getTime() != et.getTime()) {
    retArr.push(st.getYMD())

    if (st.getTime() > et.getTime()) return;
    st = new Date(yyyy, mm, ++dd); // 避免开始日期添加两次
  }

  // 将结束日期的天放进数组
  retArr.push(et.getYMD())

  return retArr // 或可换为return ret;
  // alert(retArr); // 或可换为return ret;
}

// 给Date对象添加getYMD方法,获取字符串形式的年月日
Date.prototype.getYMD = function () {
  // 将结果放在数组中,使用数组的join方法返回连接起来的字符串,并给不足两位的天和月十位上补零
  return [this.getFullYear(), fz(this.getMonth() + 1), fz(this.getDate())].join(
    '/'
  )
}

// 给String对象添加getDate方法,使字符串形式的日期返回为Date型的日期
String.prototype.getDate = function () {
  const strArr = this.split('-')
  return new Date(strArr[0], strArr[1] - 1, strArr[2])
}

// 给月和天,不足两位的前面补0
function fz(num) {
  if (num < 10) {
    num = '0' + num
  }
  return num
}

// 递归转化为对象
export function arrToObj(arr) {
  const obj = {}
  const defaultObj = {}
  for (let i = 0; i < arr.length; i++) {
    obj[i] = arr[i]
    if (Object.prototype.toString.call(arr[i]) == '[object Array]') {
      const deepArray = this.arrToObj(arr[i])
      continue
    } else {
      defaultObj[i] = arr[i]
    }
  }
  return defaultObj
}

在父组件调用封装的时间轴组件传入需要的参数即可

要实现图二的效果:拖拽了,但是前半部分依旧保持和后半部分一样的填充颜色,以具体实现时间点的效果可以修改原有组件的样式

 <div class="slider-block"><TimeSlider/></div>


.slider-block {
  width: 100%;
  padding: 40px;
  margin: auto;
  :deep().el-slider__bar{
    background-color: #e6e8ed;
  }
}

原文/参考链接:可拖动的时间轴(vue3+ts使用element-plus的Slider滑块封装)_vue时间轴拖拽组件模板_cyanempty的博客-CSDN博客

Logo

前往低代码交流专区

更多推荐