uniapp 子组件内使用定时器无法清除

涉及到的知识点:1.ref绑定在组建上获取组件实例。2.emit逆向传值,不需要点击触发,watch监听即可。

需求:在父页面的子组件定时发送请求,离开父页面就停止,再次进入就开启。

问题:在父页面的子组件内使用定时器进行发送请求,但是无法删除定时器。

试过以下方式:

我走过的弯路介绍,可直接忽略。
1.在子组件使用onShow、onLoad进行开启,使用onHide、onunLoad进行关闭,但是后来发现根本就没进入,失败。查阅资料说是组件内不支持这些。
2.跳转到其他页面就进行关闭定时器,但是这样的结果是离开当前页面后定时器永久性的关闭。
3.后来发现用vue生命周期可以进入,created,mounted,这两个可以进入定时器,但是又有问题了,只能在父组件里面才能关掉定时器,所以只有子传父将定时器计数:timer 传值给父组件,但是又有问题了,定时器关闭之后就永久关闭了,因为组件内使用的是mounted或者created 它们本身就只触发一次,没办法,只能将组件内的方法往外边带。
4.最后想到用ref,最后才成功了。
其实,最简单的办法就是不在组件里用定时器,都在一个页面里写。但是,因为业务需求 组件内容太多,所以没办法。

解决方法: 

1.在子组件内使用vue生命周期mounted或created进行定时发送请求

2.将定时器的计数timer经过逆向传值,传递给父组件,在父组件onHide周期中进行停掉

3.通过ref,在父组件进行获取到子组件身上的方法,在自身的onshow生命周期进行再次开启定时器,并在父组件onHide周期中进行停掉

父组件

<template>
  <ZiCom @child-event="handleChildEvent" ref="ZiCom"></ZiCom>
</template>

<script>
import ZiCom from "./compoment/ZiCom.vue";
export default {
  components: {
    ZiCom,
  },
  data() {
    return {
      timer: "",
      childMessage: "",
    };
  },
  onUnload() {
    uni.$off("onSuccess");
  },
  onShow() {
    // 首次执行
    this.$refs.ZiCom.getServerData();
    // 设置延迟定时器,从第二次开始正常延迟执行
    this.timer = setInterval(() => {
      this.$refs.ZiCom.getServerData();
    }, 60000);
    this.$emit("child-event", this.timer);
  },
  onHide() {
    clearInterval(this.childMessage);//清除子组件的
    clearInterval(this.timer);//清除本页面的
  },
  methods: {
    handleChildEvent(message) {
      this.childMessage = message;
    },
  },
};
</script>

子组件

<script>
export default {
  data() {
    return {
      timer: null,
    };
  },
  watch: {
    timer(newValue) {
      this.$emit("child-event", newValue);
    },
  },
  mounted() {
    // 首次执行
    this.getServerData();
    // 设置延迟定时器,从第二次开始正常延迟执行(此页面所有timer都是这个timer,为了清除定时器而使用的)
    this.timer = setInterval(() => {
      this.getServerData();
    }, 3000);
    this.$emit("child-event", this.timer);
  },
  methods: {
    getServerData() {
      //发送请求...
    },
  },
};
</script>
方案二:在父组件里写一个倒计时定时器

父组件

<template>
  <ZiCom  ref="ZiCom"></ZiCom>
</template>

<script>
import ZiCom from "./compoment/ZiCom.vue";
export default {
  components: {
    ZiCom,
  },
  data() {
    return {
      timer: "",
      childMessage: "",
    };
  },
  onUnload() {
    uni.$off("onSuccess");
  },
  onShow() {
setTimeout(()=>{
    // 首次执行
    this.$refs.ZiCom.getServerData();
    // 设置延迟定时器,从第二次开始正常延迟执行
    this.timer = setInterval(() => {
      this.$refs.ZiCom.getServerData();
    }, 60000);
},3000)
  },
  onHide() {
    clearInterval(this.timer);//清除本页面的
  },
};
</script>

 子组件

<script>
export default {
  data() {
    return {
      timer: null,
    };
  },
  methods: {
    getServerData() {
      //发送请求...
    },
  },
};
</script>

可能解决方案不是最简洁的,欢迎大家留言补充! 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值