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()
   }
相关推荐
kyriewen5 小时前
我手写了一个 EventEmitter,面试官追问了 6 个问题——第 4 个我没答上来
前端·javascript·面试
IT_陈寒5 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
山河木马6 小时前
矩阵专题2-怎么创建视图矩阵(uViewMatrix)
javascript·webgl·计算机图形学
小林攻城狮6 小时前
使用 Transport 节流解决 Vercel AI SDK 流式渲染卡死问题
前端·react.js
前端缘梦6 小时前
告别 TS 运行时类型漏洞!Zod 完整入门实战教程(前端 / 全栈必备)
前端·react.js·全栈
the_answer6 小时前
Webpack vs Vite 深度对比分析
前端·webpack
转转技术团队7 小时前
验证码识别实战:前端不写页面,改训模型了?
前端
MomentYY7 小时前
Temperature:AI 的“脑洞旋钮”
前端·llm·ai编程
远航_7 小时前
OpenSpec 完整详细介绍
前端·后端
召钱熏7 小时前
状态枚举正确≠渲染正确:一个语音按钮的状态机边界修复实录
android·前端