vue+uniapp实现一个计时器,要实现点击开始,开始计时,点击停止才停止,保持刷新,返回重新进入依旧计时并且保持连贯

vue+uniapp开发app,要实现巡检时间的技术操作,本来以为很简单,也是很多坑,效果图如下

///开发过程心历路程,可跳过,也可以看看,如果跟我第一次思路一样,劝放弃,如果你找到了好的解决办法,也请告知,程序员总是对bug耿耿于怀~~~//

第一次我的思路是:    <span class="time">{{ formattedTime }}</span>使用计算属性,    formattedTime() {
                const hours = Math.floor(this.elapsedSeconds / 3600);
                const minutes = Math.floor((this.elapsedSeconds % 3600) / 60);
                const seconds = this.elapsedSeconds % 60;
                return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
            },,,当点击开始的时候打开计时器,只有点击停止才停止,页面退回或者刷新等情况,计时器不清除,记录一下秒数在本地或者别的储存,等刷新或者重新进入的时候获取当下秒数,更新 this.elapsedSeconds++以当前秒数为起点更新

    //     this.intervalId = setInterval(() => {
                //         this.elapsedSeconds++;
                //         console.log(this.elapsedSeconds, '时间观看')
                //         localStorage.setItem('elapsedSeconds', this.elapsedSeconds);
                //         // 触发计算属性重新计算
                //         // this.$forceUpdate();
                //         // this.formattedTimes()
                //         // this.$set(this, 'elapsedSeconds', this.elapsedSeconds);
                //         // this.formattedTimes()

                //     }, 1000);

但是出现的问题就是,计时器与elapsedSeconds都在持续更新,视图不更新,计时器视图不计数,想到之前的解决办法,数据变但是视图不更新,是vue的底层原理问题,拿出解决办法,  // this.$forceUpdate();强制更新或者// this.$set(this, 'elapsedSeconds', this.elapsedSeconds);实时更新,但是都解决不了,后来换了一种思路,目前没有发现太大问题

//

1.首先我是两个组件,计时器所在的进度条为一个单独的子组件,父组件点击开始与取消或者结束按钮组要调用子组件的方法,因为我视图渲染的原因,需要等子组件渲染完毕后才可找到$refs调用,需要     this.$nextTick,

    startTimer() {
                console.log('计时开始')
                console.log(this.$refs)
                console.log(this.$refs.childrencom)
                this.$nextTick(() => {
                    this.$refs.childrencom.startpro();
                })

                // this.$refs.childrencom.startpro();
            },
            stopTimer() {
                this.$refs.childrencom.stoppro();
            },

2.模版中使用

<Progressbox ref="childrencom" :progress="10">
            </Progressbox>

3.引入注册

import Progressbox from '@/components/progressbox.vue';
    export default {
        components: {
            Progressbox
        },}

下面来看子组件

4.模版中使用计算属性

    <span class="time">{{ formattedTime }}</span>

5.data中注册,计算属性处理秒数,因为是计算的秒数,转化成时分秒形式

    data() {
            return {
                running: false,
                elapsedSeconds: 0,
                intervalId: null,
                totalseconds: 0,
                // formattedTime: ""
            }
        },
        computed: {
            formattedTime() {
                const hours = Math.floor(this.elapsedSeconds / 3600);
                const minutes = Math.floor((this.elapsedSeconds % 3600) / 60);
                const seconds = this.elapsedSeconds % 60;
                return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
            }
        },

6.方法中写开始和结束函数

    startpro() {
                console.log('时间hanshu')
                if (localStorage.getItem('firsttime') != 'null') {

                } else {
                    localStorage.setItem('firsttime', new Date());
                }

                this.intervalId = setInterval(() => {
                    this.elapsedSeconds++;
                    this.$set(this, 'elapsedSeconds', this.elapsedSeconds);
                   

                }, 1000);

    },
            stoppro() {
                console.log('取消巡检')
                clearInterval(this.intervalId);
                localStorage.setItem('firsttime', null);}

7.写钩子函数销毁

    beforeDestroy() {
            clearInterval(this.intervalId);

        }

页面重新进入与刷新都停止,重新进入的时候都会重新获取,不用再保留计时器

8.如果第一次进入开始这样就可以了,但是第二次进入页面,因为没有点击开始,直接看进行中的状态,需要在页面进入的时候也就是mounted()里面处理

    const isvalue = localStorage.getItem('firsttime')
            console.log(isvalue, 'localStorage.getItem')

            if (isvalue != 'null') {
                const nowtime = new Date()


                const timeDifference = nowtime - new Date(localStorage.getItem('firsttime'))
                this.elapsedSeconds = Math.floor(timeDifference / 1000);
                console.log(this.elapsedSeconds, 'this.elapsedSeconds')
                this.startpro()
            }

这就是目前还没发现什么大问题的版本,先记录一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值