vue做任务工具方法的实现

需求:须有普通任务(在其他页面完成指定操作,如点赞、转发等后提示完成)和浏览任务指定浏览秒数。

实现:因全局有多处时候封装成一个工具方法,且一次只能进行一个任务,设置一个开始任务类型,完成操作的时候判断改类型任务是否进行中,如果是则调用完成方法;浏览任务为设置当前任务待开始,进入指定浏览页面后判断当前待开始的任务是否数据当前浏览任务,是则开始倒计时,中途离开则中断倒计时,倒计时完成则自动调用完成方方达。当前任务进行中点击了别的任务开始则进行类型覆盖

js 复制代码
// src/stores/taskStore.ts
import { defineStore } from 'pinia';

interface TaskConfig {
    type: LifeTaskType;
    duration?: number; // 倒计时持续时间(毫秒)
    onCompleted?: () => void;
    onInterrupted?: () => void;
}

interface RunningTask extends TaskConfig {
    startTime: number;
    timerId?: number;
}

interface TaskState {
    runningTask: RunningTask | null; // 只允许一个任务运行
    pendingTask: RunningTask | null; // 待开始的任务
}

export enum LifeTaskType {
    Browse = 'browse',//浏览
    Share = 'share',//分享
    Comment = 'comment',//评论
    Publish = 'publish',//发布
    Like = 'like',//点赞
}

export const useTaskStore = defineStore('task', {
    state: (): TaskState => ({
        runningTask: null,
        pendingTask: null // 待开始的任务
    }),

    getters: {
        // 检查指定任务类型是否正在运行
        isTaskRunning: (state) => (taskType: string): boolean => {
            return state.runningTask !== null && state.runningTask.type === taskType;
        },

        // 获取当前运行的任务类型
        getCurrentTaskType: (state) => (): string | null => {
            return state.runningTask ? state.runningTask.type : null;
        },

        // 获取剩余时间
        getRemainingTime: (state) => (): number | null => {
            const task = state.runningTask;
            if (!task || !task.duration) {
                return null;
            }

            const elapsed = Date.now() - task.startTime;
            return Math.max(0, task.duration * 1000 - elapsed);
        },
    },

    actions: {
        /**
          * 开始一个任务,会停止之前运行的任务
       */
        startTask(config: TaskConfig): boolean {
            // 先停止当前运行的任务
            if (this.runningTask) {
                this.interruptCurrentTask(true);
            }

            const task: RunningTask = {
                ...config,
                startTime: Date.now(),
            };

            // 对于需要倒计时的浏览任务,先放入待开始队列
            if (config.duration) {
                // 设置为待开始状态,等待用户确认开始后才启动倒计时
                this.pendingTask = task;
                return true;
            }

            // 非浏览任务直接开始
            this.runningTask = task;
            return true;
        },



        //启动待开始的任务(开始倒计时)
        startPendingTask(): boolean {
            if (!this.pendingTask) {
                console.warn('No pending task to start');
                return false;
            }

            const task = this.pendingTask;

            // 创建倒计时
            if (task.duration) {
                const timerId = setTimeout(() => {
                    this.completeTask();
                }, task.duration * 1000);

                task.timerId = timerId as unknown as number;
            }
            console.log('开始任务', task.type)
            // 将待开始任务转为运行中任务
            this.runningTask = task;
            this.pendingTask = null;

            return true;
        },
        //获取待开始的任务
        getPendingTaskType(): LifeTaskType | null {
            return this.pendingTask?.type || null;
        },

        /**
         * 完成当前任务
         */
        async completeTask() {
            const task = this.runningTask;
            if (!task) {
                console.warn('No task is currently running');
                return false;
            }

            try {
            //这里调用完成方法
                    uni.showToast({
                        title: '恭喜你,任务完成',
                        icon: 'success',
                        duration: 3000,
                    });

                // 清理定时器
                if (task.timerId) {
                    clearTimeout(task.timerId);
                }

                // 执行完成回调
                task.onCompleted?.();
                this.pendingTask = null;
                this.runningTask = null;
            } catch (error) {
                console.error('Failed to complete task:', error);
            }
        },

        /**
         * 中断当前任务
         */
        interruptCurrentTask(isNewTask = false): boolean {
            const task = this.runningTask;
            if (!task) {
                console.warn('No task is currently running');
                return false;
            }
            console.log('中断任务', task.type)
            // 清理定时器
            if (task.timerId) {
                clearTimeout(task.timerId);
            }
            //如果不是浏览任务或新任务,清除待开始任务,保留浏览类型的浏览任务
            if (!(task.type === LifeTaskType.Browse ||  isNewTask) {
                task.onInterrupted?.();
                this.pendingTask = null;
                this.runningTask = null;
            }
            // 执行中断回调

            return true;
        },

        /**
         * 清除当前任务
         */
        clearCurrentTask() {
            const task = this.runningTask;
            if (task) {
                if (task.timerId) {
                    clearTimeout(task.timerId);
                }
                task.onInterrupted?.();
                this.pendingTask = null;
                this.runningTask = null;
            }
        }
    }
});

这里是调用:

js 复制代码
//开始浏览任务
 startTask({ type: 'browse', duration: 60 })

//开始普通任务
 startTask({ type: 'like' })


//判断当前页面进行中的任务,并在完成操作后调用
 if (isTaskRunning('like')) {
     completeTask()
   }
相关推荐
LaughingZhu6 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
怕浪猫6 小时前
Electron 开发实战(一):从零入门核心基础与环境搭建
前端·electron·ai编程
小鹏linux7 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
前端若水8 小时前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
Bigger8 小时前
mini-cc:一个轻量级 AI 编程助手的诞生
前端·ai编程·claude
涵涵(互关)8 小时前
Naive-ui树型选择器只显示根节点
前端·ui·vue
BY组态8 小时前
Ricon组态系统最佳实践:从零开始构建物联网监控平台
前端·物联网·iot·web组态·组态
BY组态8 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·物联网·iot·web组态·组态
SoaringHeart8 小时前
Flutter进阶:OverlayEntry 插入图层管理器 NOverlayZIndexManager
前端·flutter
放下华子我只抽RuiKe58 小时前
React 从入门到生产(四):自定义 Hook
前端·javascript·人工智能·深度学习·react.js·自然语言处理·前端框架