今天本来想着提交一版,但发现有一个功能没实现,那就是:每隔一段时间实时获取天气预报。
在之前的 ClockService
类中,我们使用到 setInterval(fn, 1000)
来做定时器,在当时为了一些 Typescript type 搞得焦头烂额,后来一直想着用 vueuse
,这回有了理由了。
// ClockService.ts
'use strict';
import { app } from 'electron';
const Moment = require('moment');
import LunarService from './LunarService';
export default class ClockService {
format = 'MMMDo HH:mm';
// onTickHandler: ((toString: (arg0: ClockService) => string) => void) | null = null;
onTickHandler: ((arg0: ClockService) => void) | null = null;
intervalId: NodeJS.Timeout | null = null;
params: ClockSettingParams;
constructor() {
Moment.locale(app.getLocale());
this.params = {} as ClockSettingParams;
// lll MMMDo dddd HH:mm:ss
this.setFormat('MMMDo HH:mm');
this.start();
}
start(): this {
if (typeof this.onTickHandler !== 'function') {
this.onTickHandler = () => {};
}
this.intervalId = setInterval(() => {
if (this.onTickHandler) {
this.onTickHandler(this);
}
}, 1000);
return this;
}
stop(): this {
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
return this;
}
onTick(callback: ((arg0: ClockService) => void) | null): this {
this.onTickHandler = callback;
return this;
}
}
useIntervalFn
有了 vueuse
,我们就可以直接使用 useIntervalFn vueuse.org/shared/useI…。
安装 vueuse:
yarn add @vueuse/core
首先在 setup
里重写 getWeather
方法:
const getWeather = async (location: FLocation) => {
const weatherService = new WeatherService();
weather.value = await weatherService.getWeathers(location);
};
紧接着就可以使用 vueuse 提供的函数了:
const changeShowWeather = ref(false);
const intervalFnOptions = reactive({
immediate: changeShowWeather.value,
} as IntervalFnOptions);
const { pause, resume, isActive } = useIntervalFn(() => {
getWeather(store.state.location);
}, 7200000, intervalFnOptions);
return {
weather,
eventService,
visibleFullSetting,
store,
event,
getWeather,
pause,
resume,
isActive,
changeShowWeather,
};
这样,我们就可以将对应的参数和函数 return 出去了。
在 watch 里,实时监听 changeShowWeather
值,随着设置里修改 changeShowWeather,就可以在此函数里重启或者停止该监听器:
watch: {
changeShowWeather(newval) {
this.store.commit('changeShowWeather', newval);
if (this.changeShowWeather) {
this.getWeather(this.store.state.location);
// 增加定时器,每隔2个小时更新一次天气预报
this.resume();
} else {
this.pause();
}
},
},
这样,就可以达到每隔两小时重新请求 getWeathers
获取天气预报了。
到此,我们使用到了 useIntervalFn
。
源码
学习源码是最好提升自我能力的方法,我们把源码 copy 出来给大家看看:
import { ref } from 'vue-demi'
import { tryOnUnmounted } from '../tryOnUnmounted'
import { Pausable, Fn, isClient } from '../utils'
export interface IntervalFnOptions {
/**
* Execute the callback immediate after calling this function
*
* @default true
*/
immediate?: boolean
}
/**
* Wrapper for `setInterval` with controls
*
* @param cb
* @param interval
* @param options
*/
export function useIntervalFn(cb: Fn, interval = 1000, options: IntervalFnOptions = {}): Pausable {
const {
immediate = true,
} = options
let timer: any = null
const isActive = ref(false)
function clean() {
if (timer) {
clearInterval(timer)
timer = null
}
}
function pause() {
isActive.value = false
clean()
}
function resume() {
if (interval <= 0)
return
isActive.value = true
clean()
timer = setInterval(cb, interval)
}
if (immediate && isClient)
resume()
tryOnUnmounted(pause)
return {
isActive,
pause,
resume,
}
}
接下来,我们重构刚开始说的那个 ClockService
类:
import type { Pausable } from '@vueuse/core';
export default class ClockService {
format = 'MMMDo HH:mm';
onTickHandler: ((arg0: ClockService) => void) | null = null;
pausable: Pausable;
params: ClockSettingParams;
constructor() {
Moment.locale(app.getLocale());
this.params = {} as ClockSettingParams;
// lll MMMDo dddd HH:mm:ss
this.setFormat('MMMDo HH:mm');
this.pausable = useIntervalFn(() => {
if (this.onTickHandler) {
this.onTickHandler(this);
}
}, 1000);
this.start();
}
start(): this {
if (typeof this.onTickHandler !== 'function') {
this.onTickHandler = () => {};
}
this.pausable.resume();
return this;
}
stop(): this {
this.pausable.pause();
return this;
}
这就很简单,直接看代码,不用再做解释了。
总结
我们完全可以直接参考 vueuse 提供的源代码,不需要引用这个插件,但我们发现还有很多地方可以用到,比如 @vueuse/electron 相关的功能 vueuse.org/electron/RE…,也可以在这个过程中,好好学习我心中的大神是如何封装函数和做开源代码的。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!