This is the 19th day of my participation in the Genwen Challenge
There is another direction worth playing in the refactoring process, which is to keep removing the introduced third party components one by one.
Today, I had an idea to make a countdown component by myself. The goal is to replace vue3-clock-countdown.
I looked at the source code for the vue3-clock-countdown component and it wasn’t that hard (no disrespect to the original author of course!). .
Note: I would also recommend that the original author add event related features to make it complete.
According to the effect
Without further ado, let’s look at the display effect:
- Display “day – time – minute – second” :
- Display “time-min-second” :
- Display “minute-second” :
The logic of production is to keep everything simple, simple, simple.
layout
For this layout I mainly use NCard:
Specific code:
<template>
<n-card :title="title" :bordered="false" :style="style">
<template #header-extra>
<n-button
text
style="font-size: 24px;"
@click="$emit('finish')"
>
<n-icon>
<times-circle-regular-icon />
</n-icon>
</n-button>
</template>
<n-grid x-gap="12" :cols="cols">
...
</n-grid>
</n-card>
</template>
Copy the code
So, we’re pretty much done with the header.
In the display “day – hour – minute – second” section, directly use the “layout” component, and display several NGi according to COLs:
< n - the grid - gap x = "12" : cols = "cols" > < n - gi v - if = "cols = = 4" > < n - card: the title = "formatTime (days)" size = "large" > day < / n - card > < / n - gi > < n - gi v - if = "cols > = 3" > < n - card "title =" formatTime (hours) "size =" large "> when < / n - card > < / n - gi > < n - gi > < n - card :title="formatTime(minutes)" size="large">分</n-card> </n-gi> <n-gi> <n-card :title="formatTime(seconds)" Size ="large"> seconds </n-card> </n-gi> </n-grid>Copy the code
It is too simple to say:
cols(): number {
if (this.days > 0) {
return 4;
}
if (this.hours > 0) {
return 3;
}
return 2;
},
Copy the code
You can use v-for to reduce duplicate code, and then use V-if to determine whether to display. However, in the official document of Vue, the following restrictions are clearly written: Never use V-if and V-for on the same element.
To filter items in a list (for example, v-for=”user in users” v-if=” user.isactive “). In this case, replace Users with a calculated property (such as activeUsers) and have it return the filtered list.
See: v3.cn.vuejs.org/style-guide…
Logical processing
In the logical part, there are three main aspects of data to consider:
- Time and countdown logic
seconds(): number { return Math.floor((this.currentTime / 1000) % 60); }, minutes(): number { return Math.floor((this.currentTime / 1000 / 60) % 60); }, hours(): number { return Math.floor((this.currentTime / (1000 * 60 * 60)) % 24); }, days(): number { return Math.floor(this.currentTime / (1000 * 60 * 60 * 24)); },... mounted() { setTimeout(this.countdown, 1000); }, methods: { formatTime(value: number): string { if (value < 10) { return '0' + value; } return value.toString(); }, countdown () { this.currentTime = Date.parse(this.deadline) - Date.parse(new Date()); if (this.currentTime > 0) { setTimeout(this.countdown, this.speed); } else { this.$emit('finish'); }}}Copy the code
Data moments such as seconds, minutes, hours, and days change with currentTime, so they are computed. In Mounted, the countdown is automatically executed when the component is loaded.
- Time and title
This I refer to the original author’s method, directly use the Provide/Inject method, save the assignment and import in other places.
setup() {
const deadline = inject('deadline');
const title = inject('title', '');
return {
deadline,
title,
};
},
Copy the code
- Props and emits
props: {
speed: {
type: Number,
default: 1000
},
height: Number,
},
emits: [
'finish',
],
Copy the code
Because I want to pass some properties, such as height, outside of the component, add another way to customize.
Event handling is the difference between us and the original author. We really click exit or countdown to pass the event out.
<n-button
text
style="font-size: 24px;"
@click="$emit('finish')"
>
Copy the code
summary
Now, with the custom component, we can remove the vue3-clock-countdown component.
You can continue to optimize your own components and remove third-party components to give your project more control. To be continued!
The code has been synced to Github: github.com/fanly/fanly…