涉及到的知识点: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>
可能解决方案不是最简洁的,欢迎大家留言补充!