vue3實(shí)現(xiàn)封裝時(shí)間計(jì)算-日期倒計(jì)時(shí)組件-還有XX天&第XX天
vue3封裝時(shí)間計(jì)算-日期倒計(jì)時(shí)組件——還有XX天 & 第XX天 & 年月日時(shí)分秒星期幾方法的封裝 & setup語法糖完整用法之reactive, ref, onMounted,computed
效果
1-還有幾天

2-第幾天

需求
依照服務(wù)端返回的日期與當(dāng)前日期進(jìn)行對比
- 1、返回日期大于當(dāng)前日期為 “還有XX天”
- 2、返回日期小于當(dāng)前日期為 “第XX天”
代碼
1、倒計(jì)時(shí)組件封裝
1.1、時(shí)間原則計(jì)算組件
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年迎峰度冬安全生產(chǎn)值班${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、時(shí)間展示組件
效果-大屏右上角展示時(shí)間

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、時(shí)間公共方法封裝-中文格式
XXXX年XX月XX日XX時(shí)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、時(shí)間公共方法封裝-數(shù)字格式
XXXX年XX月XX日XX時(shí)XX分XX秒 【數(shù)字格式】
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、頁面引用
效果-倒計(jì)時(shí)完整版

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的數(shù)字
const indexMethod = (index: any) => {
return index + 1
}
// interface propType {
// type: string
// }
// const props = defineProps<propType>()
const props = { type: '01' }
// 時(shí)間列表數(shù)據(jù)
const listData = reactive([
{
time: '02',
today: '周三',
date: '2022-02-02'
},
{
time: '03',
today: '周四',
date: '2022-02-03'
}
])
const lists = reactive([
{
id: '',
lineName: '',
toStation: ''
}
])
// 滑動(dòng)的元素
const scrollcontent = ref()
const totleactive = ref(0)
// interface 描述一個(gè)對象或者函數(shù)
interface matchInfo {
competitionDate: string
competitionEvent: string
}
const matchList = ref<Array<matchInfo>>([])
/**
* 根據(jù)日期得到結(jié)果
*/
const getMatch = async (date: string) => {
const res = await getMatchByDate(date)
matchList.value = res
}
/**
* 點(diǎn)擊某個(gè)日期觸發(fā)
*/
const totleMethod = (data: any, index: number) => {
totleactive.value = index
getMatch(data.date)
}
/**
* 獲取接口數(shù)據(jù)
*/
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) {
// 不在期限里, 就取數(shù)組的第一個(gè)
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;
}
}
//時(shí)間樣式
.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
/**
* 根據(jù)日期獲取接口數(shù)據(jù)
* date: 日期
*/
export const getPowerProgress = (date: string) => {
return request({
method: 'GET',
url: '/bdDailyInfo/queryBDProgress',
params: {
competitionDate: date
}
})
}
/**
* 根據(jù)時(shí)間日期獲取比賽數(shù)據(jù)
* date: 日期
*/
export const getMatchByDate = (date: string) => {
return request({
method: 'POST',
url: '/competitionInfo/selectAll',
data: {
competitionDate: date
}
})
}
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Vue3實(shí)現(xiàn)獲取驗(yàn)證碼按鈕倒計(jì)時(shí)效果
- Vue3動(dòng)態(tài)倒計(jì)時(shí)的代碼實(shí)現(xiàn)
- Vue3+Hooks實(shí)現(xiàn)4位隨機(jī)數(shù)和60秒倒計(jì)時(shí)的示例代碼
- 基于Vue3創(chuàng)建一個(gè)簡單的倒計(jì)時(shí)組件
- vue3發(fā)送驗(yàn)證碼倒計(jì)時(shí)功能的實(shí)現(xiàn)(防止連點(diǎn)、封裝復(fù)用)
- Vue3?實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能
- Vue3?實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能(刷新保持狀態(tài))
- 使用Vue3實(shí)現(xiàn)倒計(jì)時(shí)器及倒計(jì)時(shí)任務(wù)的完整代碼
相關(guān)文章
VUE+Canvas實(shí)現(xiàn)簡單五子棋游戲的全過程
這篇文章主要給大家介紹了關(guān)于VUE+Canvas實(shí)現(xiàn)簡單五子棋游戲的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
詳解vue-cil和webpack中本地靜態(tài)圖片的路徑問題解決方案
這篇文章主要介紹了詳解vue-cil和webpack中本地靜態(tài)圖片的路徑問題解決方案,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09
關(guān)于element中el-cascader的使用方式
這篇文章主要介紹了關(guān)于element中el-cascader的使用方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
利用Vue與D3.js創(chuàng)建交互式數(shù)據(jù)可視化
在現(xiàn)代Web開發(fā)中,數(shù)據(jù)可視化是一個(gè)引人矚目的熱點(diǎn)領(lǐng)域,從簡單的圖表到復(fù)雜的交互式儀表盤,數(shù)據(jù)可視化能夠幫助用戶更好地理解數(shù)據(jù),而Vue與D3.js的結(jié)合則為我們提供了構(gòu)建這些可視化效果的強(qiáng)大工具,本文將向您展示如何利用Vue與D3.js創(chuàng)建一個(gè)基本的交互式數(shù)據(jù)可視化項(xiàng)目2025-02-02
Vue.js實(shí)現(xiàn)動(dòng)畫與過渡效果的示例代碼
在現(xiàn)代前端開發(fā)中,用戶體驗(yàn)至關(guān)重要,一個(gè)精美的動(dòng)畫過渡不僅能提升界面的美觀性,還能讓用戶在使用時(shí)感受到流暢的交互體驗(yàn),在本文中,我們將深入探討如何在 Vue.js 中實(shí)現(xiàn)動(dòng)畫與過渡效果,并提供示例代碼,需要的朋友可以參考下2024-10-10
Vue如何實(shí)現(xiàn)文件預(yù)覽和下載功能的前端上傳組件
在Vue.js項(xiàng)目中,使用ElementUI的el-upload組件可以輕松實(shí)現(xiàn)文件上傳功能,通過配置組件參數(shù)和實(shí)現(xiàn)相應(yīng)的方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09
vue中子組件向父組件傳遞數(shù)據(jù)的實(shí)例代碼(實(shí)現(xiàn)加減功能)
這篇文章主要介紹了vue中子組件向父組件傳遞數(shù)據(jù)的實(shí)例代碼(實(shí)現(xiàn)加減功能) ,需要的朋友可以參考下2018-04-04

