博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

用vue实现一个常见的时间显示效果

Posted on 2022-09-09 15:27  地霊殿~三無  阅读(2376)  评论(0编辑  收藏  举报

一、前言

相信大家应该也经常遇见要实现一个类似时间的效果,类似这种一般都是做成通用的组件,方便在各个系统内移植使用,如下图这种效果

image.png

下面我就献丑,带大家伙简单来实现下以下效果,样式比较粗糙,大家可以直接拿函数方法就好。

二、实现过程

1、思路

要实现这种时间效果,可以借助定时器做到,每秒调用一次函数来更新显示即可
复制代码

2、主要说下js的部分

我们需要一个定时器,一个保存时间的变量

data() {
    return {
      // 时间组件
      timer: null, // 定时器
      time: {}
    }
},
复制代码

然后是一个定时函数,间隔为1s

mounted() {
    // 在挂载期间定时调用
    this.timer = setInterval(() => {
      this.getDate() // 要调用的函数
    }, 1000)
  },
复制代码

然后是getDate函数的实现

 // 获取当前时间显示
getDate() {
  this.time = this.parseTime(new Date()) // 这里只是获取当前时间,传参而已
  console.log(this.time)
},
复制代码

最后才是重头戏的parseTime函数,该函数负责处理转化当前时间变成包含我们需要的信息的对象。

  // 根据传入的时间,处理成需要的对象函数
parseTime(time, cFormat) {
  const resObj = {}
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string')) {
      if ((/^[0-9]+$/.test(time))) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }

    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
    return value.toString().padStart(2, '0')
  })

  resObj.week = ['日', '一', '二', '三', '四', '五', '六'][formatObj.a]
  resObj.mark = ['通宵加班', '加班', '摸鱼', '摸鱼', '摸鱼', '加班', '加班填坑'][formatObj.a]
  resObj.timeStr = time_str

  for (const key in formatObj) {
    if (formatObj.hasOwnProperty(key)) {
      const element = formatObj[key]
      resObj[key] = element.toString().padStart(2, '0')
    }
  }
  return resObj
}
复制代码

下图就是处理完的结构,如果还没满意要求,可以自行添加属性

image.png

3、完整部分

调用time.vue的部分

<!-- // 调用时间组件,div部分 -->
<div style="position: absolute; left: 100px; top: 210px">
  <Time />
</div>

// 局部引入
import Time from './components/time.vue'

export default {
  components: {
    Time
  },
}
复制代码

time.vue部分

<template>
  <div class="time">
    <div class="time-left">
      <span class="span1"> {{ time.timeStr.split(' ')[1] }}</span>
      <span class="span2"> {{ time.timeStr.split(' ')[0] }}</span>
    </div>
    <div class="time-right">
      <span class="span1">
        今日{{ time.mark }}
      </span>
      <span class="span2">
        星期{{ time.week }}
      </span>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Time',
  data() {
    return {
      // 时间组件
      timer: null,
      time: {}
    }
  },
  watch: {
  },
  created() {
  },
  mounted() {
    // 在挂载期间定时调用
    this.timer = setInterval(() => {
      this.getDate()
    }, 1000)
  },
  beforeDestroy() {
    // 摧毁组件前销毁定时器
    clearInterval(this.timer)
    this.timer = null
  },
  methods: {
    // 获取当前时间显示
    getDate() {
      this.time = this.parseTime(new Date())
      console.log(this.time)
    },
    // 根据传入的时间,处理成需要的对象函数
    parseTime(time, cFormat) {
      const resObj = {}
      if (arguments.length === 0 || !time) {
        return null
      }
      const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
      let date
      if (typeof time === 'object') {
        date = time
      } else {
        if ((typeof time === 'string')) {
          if ((/^[0-9]+$/.test(time))) {
            // support "1548221490638"
            time = parseInt(time)
          } else {
            // support safari
            // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
            time = time.replace(new RegExp(/-/gm), '/')
          }
        }

        if ((typeof time === 'number') && (time.toString().length === 10)) {
          time = time * 1000
        }
        date = new Date(time)
      }
      const formatObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
      }
      const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
        const value = formatObj[key]
        // Note: getDay() returns 0 on Sunday
        if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
        return value.toString().padStart(2, '0')
      })

      resObj.week = ['日', '一', '二', '三', '四', '五', '六'][formatObj.a]
      resObj.mark = ['通宵加班', '加班', '摸鱼', '摸鱼', '摸鱼', '加班', '加班填坑'][formatObj.a]
      resObj.timeStr = time_str

      for (const key in formatObj) {
        if (formatObj.hasOwnProperty(key)) {
          const element = formatObj[key]
          resObj[key] = element.toString().padStart(2, '0')
        }
      }
      return resObj
    }
  }
}
</script>
<style lang="scss" scoped>
.time {
  // float: right;
  display: flex;
  height: 64px;
  color: #000;
  margin-right: 10px;
  &-left {
    margin-left: 8px;
    margin-top: 10px;
    display: flex;
    flex-direction: column;
    .span1 {
      line-height: 28px;
      font-size: 20px;
      font-weight: bold;
    }
    .span2 {
      line-height: 20px;
    }
  }
  &-right {
    display: flex;
    flex-direction: column;
    margin-left: 8px;
    margin-top: 10px;
    .span1 {
      line-height: 28px;
      font-size: 20px;
      font-weight: bold;
    }
    .span2 {
      line-height: 20px;
    }
  }
}
</style>
复制代码

三、总结

类似这类组件,一般可以做成通用的组件,或者把函数做成通用的就行。

ps: 浅浅水一个

Snipaste_2022-07-19_15-30-26.jpg


作者:地霊殿__三無
链接:https://juejin.cn/post/7133617152057147423
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Live2D