前言:
用vue3如何来实现一个滚动的时钟效果呢?这里来分享下方法。
注意,因为vue3很多写法都不同,所以这里多分享点东西。
实现效果:
实现步骤:
1、路由添加
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/a',
name: 'ScrollTime',
component: () => import('../components/scrollTime.vue')
}
]
})
export default router
2、在components里面新建一个scrllTime.vue文件
首先引入配置,因为vue3是按需引入,把需要的内容导入
import {
defineComponent,
reactive,
watch,
toRefs,
onMounted,
} from 'vue'
其次,开始他的具体方法定义
1)data数据定义,实现双向绑定方法
const data = reactive({})
return {
...toRefs(data),
}
2)methods方法定义
setup() {
function abc(){}
function clickFun(){}
return{
clickFun, //发送以后,界面上就可以调用了
}
}
3)生命周期,mounted方法使用
//初始化调用,如果是create方法,直接在setup里面调用就行
onMounted(() => {
getTime()
})
3)watch监听
setup(){
//watch监听机型
watch(
() => data.index5,
(newVal) => {
debugger
// 超过24小时
if (data.index6 === 2 && newVal === 4) {
for (let i = 1; i < 7; i++) {
data[`index${i}`] = 0
}
}
},
)
}
源码:
<template>
<div class="wraper">
<div class="column" :style="{transform: `translateY(${-lineHeight*index6}px)`}">
<div class="num" v-for="(item, index) in arr6" :key="index">{{ item }}</div>
</div>
<div class="column" :style="{transform: `translateY(${-lineHeight*index5}px)`}">
<div class="num" v-for="(item, index) in arr5" :key="index">{{ item }}</div>
</div>
<div>:</div>
<div class="column" :style="{transform: `translateY(${-lineHeight*index4}px)`}">
<div class="num" v-for="(item, index) in arr4" :key="index">{{ item }}</div>
</div>
<div class="column" :style="{transform: `translateY(${-lineHeight*index3}px)`}">
<div class="num" v-for="(item, index) in arr3" :key="index">{{ item }}</div>
</div>
<div>:</div>
<div class="column" :style="{transform: `translateY(${-lineHeight*index2}px)`}">
<div class="num" v-for="(item, index) in arr2" :key="index">{{ item }}</div>
</div>
<div class="column" :style="{transform: `translateY(${-lineHeight*index1}px)`}">
<div class="num" v-for="(item, index) in arr1" :key="index">{{ item }}</div>
</div>
</div>
</template>
<script>
import {
defineComponent,
reactive,
watch,
toRefs,
onMounted,
} from 'vue'
export default defineComponent ({
name: "ScrollTime",
setup() {
/************************ todo-定义数据data(START) ************************/
const data = reactive({
lineHeight: 64, //跟字体大小和wraper的高度相关!
// 秒
arr1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
index1: 0, //就是获取真实时间后的起始数字
arr2: [0, 1, 2, 3, 4, 5],
index2: 0,
// 分
arr3: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
index3: 0,
arr4: [0, 1, 2, 3, 4, 5],
index4: 0,
// 时
arr5: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
index5: 0,
arr6: [0, 1, 2],
index6: 0
})
/************************ todo-定义数据data(END) ************************/
/************************ todo-生命周期(START) ************************/
onMounted(() => {
getTime()
})
//watch监听机型
watch(
() => data.index5,
(newVal) => {
debugger
// 超过24小时
if (data.index6 === 2 && newVal === 4) {
for (let i = 1; i < 7; i++) {
data[`index${i}`] = 0
}
}
},
)
/************************ todo-生命周期(END) ************************/
/************************ todo-methods(START) ************************/
function getTime() {
const date = new Date()
let hour = bu0(date.getHours())
let minute = bu0(date.getMinutes())
let second = bu0(date.getSeconds())
// 秒
data.index1 = +second[1]
data.index2 = +second[0]
// 分
data.index3 = +minute[1]
data.index4 = +minute[0]
// 时
data.index5 = +hour[1]
data.index6 = +hour[0]
turnSecond(data.arr1.length)
}
function turnSecond(length) {
setInterval(() => {
if (data.index1 === length - 1) {
// 通知前一位移动
turnOther(2, data.arr2.length)
data.index1 = -1
}
data.index1++
}, 1000)
}
function bu0(num) {
let str
if (num < 10) str = `0${num}`
else str = `${num}`
return str.split('')
}
function turnOther(type, length) {
// type代表第几组数列,例如2,就是从右往左第二列
if (data[`index${type}`] === length - 1) {
// console.log(type)
// 通知前一位移动
let next = type + 1
turnOther(next, data[`arr${next}`].length)
data[`index${type}`] = -1
}
data[`index${type}`]++
}
/************************ todo-methods(END) ************************/
return {
//数据
...toRefs(data),
}
}
})
</script>
<style scoped>
.wraper {
text-align: center;
background: #ffffff;
height: 64px;
font-size: 48px;
font-weight: bolder;
letter-spacing: 7px;
margin-top: 7px;
display: flex;
justify-content: center;
overflow:hidden;
}
.column {
transition: transform 300ms;
}
.num {
height: 64px;
}
</style>