效果如图所示
如果想直接用可以复制代码当作vue组件。
实现原理
时钟实际上是六个独立的纵向数列,每列的数字从下往上滚动,秒数滚动到头就向左“进一位”,每一列到头都会向左“进一位”。
到24:00:00时全部从0开始。
获取当前时间后,把值赋给每一位数字,然后就按上面的流程每秒滚动一次,来模拟时钟。
由于js的计时不够精确,运行时间长可能错几秒。
组件代码
<template><view><view class="wraper"><view class="column" :style="{transform: `translateY(${-lineHeight*index6}px)`}"><view class="num" v-for="(item, index) in arr6" :key="index">{{ item }}</view></view><view class="column" :style="{transform: `translateY(${-lineHeight*index5}px)`}"><view class="num" v-for="(item, index) in arr5" :key="index">{{ item }}</view></view><view>:</view><view class="column" :style="{transform: `translateY(${-lineHeight*index4}px)`}"><view class="num" v-for="(item, index) in arr4" :key="index">{{ item }}</view></view><view class="column" :style="{transform: `translateY(${-lineHeight*index3}px)`}"><view class="num" v-for="(item, index) in arr3" :key="index">{{ item }}</view></view><view>:</view><view class="column" :style="{transform: `translateY(${-lineHeight*index2}px)`}"><view class="num" v-for="(item, index) in arr2" :key="index">{{ item }}</view></view><view class="column" :style="{transform: `translateY(${-lineHeight*index1}px)`}"><view class="num" v-for="(item, index) in arr1" :key="index">{{ item }}</view></view></view></view></template><script>export default {data() {return {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,}},created() {this.getTime()},watch: {index5(newVal) {// 超过24小时if (this.index6 === 2 && newVal===4) {console.log('out')for (let i=1; i<7; i++) {this[`index${i}`] = 0}}}},methods: {getTime() {const date = new Date()let hour = this.bu0(date.getHours()) let minute = this.bu0(date.getMinutes()) let second = this.bu0(date.getSeconds()) // 测试用// let hour = ['1', '9']// let minute = ['5', '9']// let second = ['5', '5']// 秒this.index1 = parseInt(second[1])this.index2 = parseInt(second[0])// 分this.index3 = parseInt(minute[1])this.index4 = parseInt(minute[0])// 时this.index5 = parseInt(hour[1])this.index6 = parseInt(hour[0])this.turnSecond(this.arr1.length)},bu0(num) {let strif (num < 10) str = `0${num}`else str = `${num}`return str.split('')},turnSecond (length) {setInterval(()=> {if (this.index1 === length-1) {// console.log(1)// 通知前一位移动this.turnOther( 2, this.arr2.length)this.index1 = -1}this.index1++}, 1000)},turnOther(type, length) {// type代表第几组数列,例如2,就是从右往左第二列if (this[`index${type}`] === length-1) {// console.log(type)// 通知前一位移动let next = type+1this.turnOther( next, this[`arr${next}`].length)this[`index${type}`] = -1}this[`index${type}`]++}}}</script><style lang="scss" scoped>.wraper {text-align: center;background-color: #ffffff;height: 64px;font-family: "Microsoft YaHei";font-size: 48px;font-weight: bolder;letter-spacing: 7px;margin-top: 7px;display: flex;justify-content: center;.column {transition: transform 300ms;.num {height: 64px;}}}</style>
代码如上,难点是turnOther函数,它是个自调用函数,用来实现“进位”。
如果觉得《前端用vue实现一个滚动数字时钟》对你有帮助,请点赞、收藏,并留下你的观点哦!