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

2-第幾天

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

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、時間公共方法封裝-數(shù)字格式
XXXX年XX月XX日XX時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ì)時完整版

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ù)據(jù)
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 描述一個對象或者函數(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)擊某個日期觸發(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ù)組的第一個
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
/**
* 根據(jù)日期獲取接口數(shù)據(jù)
* date: 日期
*/
export const getPowerProgress = (date: string) => {
return request({
method: 'GET',
url: '/bdDailyInfo/queryBDProgress',
params: {
competitionDate: date
}
})
}
/**
* 根據(jù)時間日期獲取比賽數(shù)據(jù)
* date: 日期
*/
export const getMatchByDate = (date: string) => {
return request({
method: 'POST',
url: '/competitionInfo/selectAll',
data: {
competitionDate: date
}
})
}
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
- Vue3實(shí)現(xiàn)獲取驗(yàn)證碼按鈕倒計(jì)時效果
- Vue3動態(tài)倒計(jì)時的代碼實(shí)現(xiàn)
- Vue3+Hooks實(shí)現(xiàn)4位隨機(jī)數(shù)和60秒倒計(jì)時的示例代碼
- 基于Vue3創(chuàng)建一個簡單的倒計(jì)時組件
- vue3發(fā)送驗(yàn)證碼倒計(jì)時功能的實(shí)現(xiàn)(防止連點(diǎn)、封裝復(fù)用)
- Vue3?實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時功能
- Vue3?實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時功能(刷新保持狀態(tài))
- 使用Vue3實(shí)現(xiàn)倒計(jì)時器及倒計(jì)時任務(wù)的完整代碼
相關(guān)文章
Vue3中defineProps設(shè)置默認(rèn)值的方法實(shí)現(xiàn)
Vue3中我們經(jīng)常需要使用defineProps來定義組件的屬性,本文主要介紹了Vue3中defineProps設(shè)置默認(rèn)值的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07
Vue3 中 watch的 flush 選項(xiàng)(默認(rèn)無/`post`/`sync`
文章介紹了Vue3中watch的flush選項(xiàng),解釋了三種模式(默認(rèn)pre、post、sync)的工作機(jī)制和適用場景,并提供了代碼示例進(jìn)行對比,強(qiáng)調(diào)了在90%的場景下選擇post模式以確保操作DOM的正確性,感興趣的朋友跟隨小編一起看看吧2026-03-03
vue本地打開build后生成的dist文件夾index.html問題
這篇文章主要介紹了vue本地打開build后生成的dist文件夾index.html問題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友參考下吧2019-09-09
vue-cli如何修改打包項(xiàng)目結(jié)構(gòu)及前綴
這篇文章主要介紹了vue-cli如何修改打包項(xiàng)目結(jié)構(gòu)及前綴問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
vue中圖片轉(zhuǎn)base64格式實(shí)現(xiàn)方法
這篇文章主要介紹了vue中圖片轉(zhuǎn)base64格式實(shí)現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
VUE?el-table列表搜索功能純前端實(shí)現(xiàn)方法
Vue表搜索是指在Vue應(yīng)用中實(shí)現(xiàn)對表格數(shù)據(jù)的搜索功能,下面這篇文章主要給大家介紹了關(guān)于VUE?el-table列表搜索功能純前端實(shí)現(xiàn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09
vue2項(xiàng)目導(dǎo)出操作實(shí)現(xiàn)方法(后端接口導(dǎo)出、前端直接做導(dǎo)出)
這篇文章主要給大家介紹了關(guān)于vue2項(xiàng)目導(dǎo)出操作實(shí)現(xiàn)方法的相關(guān)資料,文中介紹的是后端接口導(dǎo)出、前端直接做導(dǎo)出,通過代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-05-05

