vue3实现封装时间计算-日期倒计时组件-还有XX天&第XX天

 更新时间:2024年03月18日 10:33:16   作者:viceen  
这篇文章主要介绍了vue3实现封装时间计算-日期倒计时组件-还有XX天&第XX天,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

vue3封装时间计算-日期倒计时组件——还有XX天 & 第XX天 & 年月日时分秒星期几方法的封装 & setup语法糖完整用法之reactive, ref, onMounted,computed

效果

1-还有几天

2-第几天

需求

依照服务端返回的日期与当前日期进行对比

  • 1、返回日期大于当前日期为 “还有XX天”
  • 2、返回日期小于当前日期为 “第XX天”

代码

1、倒计时组件封装

1.1、时间原则计算组件

src/components/header/countDown.vue

<script lang="ts" setup>
import { ref } from 'vue'
const days = ref(3)
const condition = ref('还有/第')
const text = ref(`距2021-2022年迎峰度冬安全生产值班${condition.value}${days.value}天`)
</script>

<template>
  <div class="days">
    <!--1.0、封装 -->
    {{ text }}
  </div>
</template>

<style scoped>
  .days {
    color: #FFFFFF;
    font-size: 20px;
    position: relative;
    left: 20px;
    top: 50px;
    width: 600px;
  }
</style>

1.2、时间展示组件

效果-大屏右上角展示时间

src/components/header/date.vue

<template>
  <div>{{ date }}</div>
</template>

<script lang="ts" setup>
import formatter from '@/utils/formatterData'
import { ref, onMounted } from 'vue'
const date = ref('')
onMounted(() => {
  setInterval(() => {
    getDate()
  }, 1000)
})

const getDate = function () {
  date.value = formatter(new Date())
}
</script>

<style scoped lang="scss">

</style>

1.3、时间公共方法封装-中文格式

XXXX年XX月XX日XX时XX分XX秒 星期X

src/utils/formatterData.ts

const complement = function (value:any) {
  return value < 10 ? `0${value}` : value
}

export default (date:any) => {
  const time = new Date(date)
  const year = time.getFullYear()
  const month = complement(time.getMonth() + 1)
  const day = complement(time.getDate())
  const hour = complement(time.getHours())
  const minute = complement(time.getMinutes())
  const second = complement(time.getSeconds())
  const week = '星期' + '日一二三四五六'.charAt(time.getDay())
  return `${year}年-${month}-月${day}日 ${week} ${hour}:${minute}:${second}`
}

1.4、时间公共方法封装-数字格式

XXXX年XX月XX日XX时XX分XX秒 【数字格式】

src/utils/date.ts

/*
 * @Author: CL
 * @Date: 2021-10-21 14:09:07
 * @LastEditTime: 2021-10-21 16:28:55
 * 工具方法
 */

export const formatTime = (data: Date | string, flag: boolean) => {
  const date = new Date(data)
  const y = date.getFullYear()
  let m: number | string = date.getMonth() + 1
  m = m < 10 ? ('0' + m) : m
  let d : number | string = date.getDate()
  d = d < 10 ? ('0' + d) : d
  let h : number | string = date.getHours()
  h = h < 10 ? ('0' + h) : h
  let minute : number | string = date.getMinutes()
  minute = minute < 10 ? ('0' + minute) : minute
  let second: number | string = date.getSeconds()
  second = second < 10 ? ('0' + second) : second
  if (flag) {
    return y + '-' + m + '-' + d
  }
  return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second
}

2、页面引用

效果-倒计时完整版

index.vue

<script setup lang="ts">
import { reactive, ref, computed, onMounted } from 'vue'
import { getPowerProgress, getMatchByDate } from '@/api/olympicWinter/left/Match_Schedule.ts'
// 2.0、引用
import countDown from '@/components/header/countDown.vue'
import date from '@/components/header/date.vue'
import { formatTime } from '@/utils/utils'

// 生成 0-n的数字
const indexMethod = (index: any) => {
  return index + 1
}

// interface propType {
//  type: string
// }
// const props = defineProps<propType>()
const props = { type: '01' }

// 时间列表数据
const listData = reactive([
  {
    time: '02',
    today: '周三',
    date: '2022-02-02'
  },
  {
    time: '03',
    today: '周四',
    date: '2022-02-03'
  }
])

const lists = reactive([
  {
    id: '',
    lineName: '',
    toStation: ''
  }
])

// 滑动的元素
const scrollcontent = ref()
const totleactive = ref(0)

// interface  描述一个对象或者函数
interface matchInfo {
  competitionDate: string
  competitionEvent: string
}
const matchList = ref<Array<matchInfo>>([])
/**
 * 根据日期得到结果
 */
const getMatch = async (date: string) => {
  const res = await getMatchByDate(date)
  matchList.value = res
}

/**
 * 点击某个日期触发
 */
const totleMethod = (data: any, index: number) => {
  totleactive.value = index
  getMatch(data.date)
}

/**
 * 获取接口数据
 */
const getProgress = async () => {
  const time = new Date()
  const nowTime = formatTime(time, true)
  const res = await getPowerProgress(nowTime)
  console.log(res, 'kkkk')
  const temp = listData.filter((item: any) => {
    return item.date === nowTime
  })
  if (temp.length <= 0) {
    // 不在期限里, 就取数组的第一个
    getMatch(listData[0].date)
  } else {
    getMatch(nowTime)
  }
}

onMounted(() => {
  getProgress()
})

const textType = computed(() => {
  let text = ''
  if (props.type === '01') {
    text = '线路名称'
  } else if (props.type === '02') {
    text = '变电站名称'
  } else if (props.type === '03') {
    text = '用户名称'
  }
  return text
})
</script>


<template>
  <div class="main-container">
    <div class="head-container">
      <div class="head-content">
        <!--3.0、使用 -->
        <countDown />
        <div class="left" />
        <div class="main">
          <div class="left" />
          <div class="right">
            <date />
          </div>
        </div>
      </div>
      <div class="count">
        <!-- 3.1、ref和interface 定义变量的用法 -->
        <div
          v-for="(item, index) in matchList"
          :key="index"
        >
          <span>{{ item.competitionDate }}</span>
          <span>{{ item.competitionEvent }}</span>
        </div>
        <!-- 3.2、reactive 定义变量的用法 -->
        <div
          class="scroll"
          ref="scrollcontent"
        >
          <div
            :class="[totleactive === index ? 'totleactive' : 'totlebox']"
            v-for="(item,index) in listData"
            :key="index"
            @click="totleMethod(item, index)"
          >
            <p>{{ item.time }}</p>
            <p>{{ item.today }}</p>
          </div>
        </div>
        <!-- 3.3、onMounted 定义变量的用法 -->
        <div>
          <span>{{ textType }}</span>
        </div>
        <div>
          <el-table :data="lists">
            <el-table-column
              prop="lineName"
              label="序号"
              type="index"
              align="center"
              width="80"
              :index="indexMethod"
            />
            <el-table-column
              prop="toStation"
              align="center"
              :label="textType"
            />
          </el-table>
        </div>
      </div>
    </div>
  </div>
</template>
<style scoped lang="scss">
.main-container {
  width: 7660px;
  height: 1070px;
  display: grid;
  padding: 0 10px 10px;
  grid-gap: 0 10px;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 120px auto;
  background-image: url(@/assets/yfdd-bs/bg.png);
  background-size: cover;
  color: #fff;
  font-size: 23px;
  grid-template-areas:
    "a a a a"
    "b c c d";
  .head-container {
    height: 120px;
    background-image: url(@/assets/yfdd-bs/title.png);
    background-repeat: no-repeat;
    background-size: contain;
    background-position: center;
    grid-area: a;
    display: flex;
  }
  .head-content {
    width: 100%;
    display: flex;
    background-repeat: no-repeat;
    background-size: contain;
    background-position: center;
    cursor: pointer;
    .left {
      width: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-left: -200px;
    }
    .main {
      width: 53%;
      display: flex;
      justify-content: end;
    }
    .left {
      width: 50%;
    }
    .right {
      display: flex;
      justify-content: right;
      line-height: 145px;
      font-size: 40px;
    }
  }

  //时间样式
  .scroll {
    width: 2000px;
    display: flex;
    transition: all 2s;
    // transform: all 1s;
    // margin-left: -600px;
    // justify-content: space-around;
    .totlebox {
      // width: 53px;
      // height: 53px;
      cursor: pointer;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      margin: 0 29px;
      padding: 4px;
      margin-top: 5px;
      p {
        font-size: 24px;
        font-family: PingFangSC;
        font-weight: bold;
        color: #ffffff;
      }
      p:nth-child(2) {
        font-size: 16px;
      }
    }
    .totleactive {
      width: 53px;
      height: 53px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      background: #1269c2;
      border-radius: 50%;
      align-items: center;
      margin: 0 29px;
      padding: 4px;
      margin-top: 5px;
      p {
        font-size: 24px;
        font-family: PingFangSC;
        font-weight: bold;
        color: #ffffff;
      }
      p:nth-child(2) {
        font-size: 16px;
      }
    }
  }
}
</style>

接口

src/api/olympicWinter/left/Match_Schedule.ts

/**
 * 根据日期获取接口数据
 * date: 日期
 */
export const getPowerProgress = (date: string) => {
  return request({
    method: 'GET',
    url: '/bdDailyInfo/queryBDProgress',
    params: {
      competitionDate: date
    }
  })
}

/**
 * 根据时间日期获取比赛数据
 * date: 日期
 */
export const getMatchByDate = (date: string) => {
  return request({
    method: 'POST',
    url: '/competitionInfo/selectAll',
    data: {
      competitionDate: date
    }
  })
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Vue2中引入使用ElementUI的教程详解

    Vue2中引入使用ElementUI的教程详解

    这篇文章主要为大家详细介绍了Vue2中引入使用ElementUI教程的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的可以参考下
    2024-03-03
  • antd vue 如何调整checkbox默认样式

    antd vue 如何调整checkbox默认样式

    这篇文章主要介绍了antd vue 如何调整checkbox默认样式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Vue中Vue-Baidu-Map基本使用方法实例

    Vue中Vue-Baidu-Map基本使用方法实例

    最近有一个项目需要用到地图来展示位置并进行数据交互,用vue-baidu-map实现出来,下面这篇文章主要给大家介绍了关于Vue中Vue-Baidu-Map基本使用的相关资料,需要的朋友可以参考下
    2023-03-03
  • Vue实现Base64编码与解码的代码示例

    Vue实现Base64编码与解码的代码示例

    在Web开发中,Base64编码常用于将二进制数据转换为文本字符串,以便在网络上传输,在Vue.js应用中,Base64编码广泛应用于图像的嵌入,本文将详细介绍如何在Vue.js中实现Base64编码与解码,并提供多种示例和实现思路,需要的朋友可以参考下
    2024-09-09
  • 浅谈vue项目利用Hbuilder打包成APP流程,以及遇到的坑

    浅谈vue项目利用Hbuilder打包成APP流程,以及遇到的坑

    这篇文章主要介绍了浅谈vue项目利用Hbuilder打包成APP流程,以及遇到的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • vue2老项目vite升级改造过程记录

    vue2老项目vite升级改造过程记录

    目前vite主要默认是支持给vue3使用的,并且如果使用官方的cli创建的项目一样会默认使用vue3去构建项目,此时对于一些vue2的老项目就显得不友好了,下面这篇文章主要给大家介绍了关于vue2老项目vite升级改造的相关资料,需要的朋友可以参考下
    2022-12-12
  • Vue中插槽和过滤器的深入讲解

    Vue中插槽和过滤器的深入讲解

    Vue插槽,是学习vue中必不可少的一节,越来越发现插槽的好用,而过滤数据也是我们日常开发中必然会用到的,这篇文章主要给大家介绍了关于Vue插槽和过滤器的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-07-07
  • Vuex之理解state的用法实例

    Vuex之理解state的用法实例

    本篇文章主要介绍了Vuex之理解state的用法实例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • vue中的rem如何配置

    vue中的rem如何配置

    这篇文章主要介绍了vue中的rem如何配置,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • 利用vite创建vue3项目的全过程及一个小BUG详解

    利用vite创建vue3项目的全过程及一个小BUG详解

    Vite作为一个构建工具,提供了一种快速的方法来构建Vue应用,而Vue3 则是一个前端框架,提供了强大的功能来构建和管理前端项目,下面这篇文章主要给大家介绍了关于利用vite创建vue3项目的全过程及一个小BUG的相关资料,需要的朋友可以参考下
    2023-04-04

最新评论