App端用户每日弹出签到弹窗如何实现?(uniapp+Vue)

需求:

  • 后端提供接口返回用户签到信息。
  • 应用启动或重新展示时,若用户未签到,需要弹出签到弹窗;已签到则不弹。
  • 签到成功后自动关闭弹窗。

思路:

  1. App.vueonShow 生命周期做全局判断,确保在任意页面激活时都能检查签到状态。
  2. 在签到弹窗页 pages/checkIn/checkIn.vue 中负责: 拉取签到详情、渲染奖励列表、调用签到接口并在成功后自动关闭。

实现步骤:

  1. 封装接口调用方法
js 复制代码
 // 获取签到信息
  getSigninInfoApi(data) {
    return http.get("/api/sign_in/info", { params: data || {} });
  },
  // 执行签到
  signInApi(data) {
    return http.post("/api/sign_in/sign", { data: data || {} });
  },
  1. 全局入口检查签到状态 (App.vue)
js 复制代码
import { loginApi } from '@/api/login.js';

const checkSigninStatus = async () => {
  // Step 1. 检查 token 是否存在,没有登录用户不触发签到逻辑
  const token = uni.getStorageSync('token');
  if (!token) return;

  try {
    // Step 2. 请求签到状态接口
    const res = await loginApi.getSigninInfoApi({});
    if (res?.code !== 1) return; // 接口异常直接退出

    const hasSignedToday = !!res?.data?.is_signed_today;
    if (hasSignedToday) return; // 已签到则不弹窗

    // Step 3. 打开签到弹窗(防止重复跳转)
    const openPopup = () => {
      const pages = getCurrentPages();
      const currentPage = pages[pages.length - 1];
      if (!currentPage || currentPage.route === 'pages/checkIn/checkIn') return;

      // 轻微延迟防止路由冲突
      uni.navigateTo({
        url: '/pages/checkIn/checkIn'
      });
    };

    setTimeout(openPopup, 300);
  } catch (e) {
    console.error('检查签到状态失败:', e);
  }
};

// 在 App.vue 的 onShow 生命周期中触发
onShow(() => {
  checkSigninStatus();
});
  1. 签到弹窗逻辑 (pages/checkIn/checkIn.vue)
  • 页面加载时展示签到按钮。
  • 点击"签到"后调用 loginApi.signInApi()
  • 签到成功后弹出提示并自动关闭弹窗。
js 复制代码
// pages/checkIn/checkIn.vue
import { loginApi } from '@/api/login.js';

const loading = ref(false);       // 按钮加载状态
const isSignedToday = ref(false); // 是否已签到

// 页面加载时拉取签到状态
onShow(async () => {
  const res = await loginApi.getSigninInfoApi({});
  if (res?.code === 1) {
    isSignedToday.value = !!res.data.is_signed_today;
  }
});

// 点击"立即签到"按钮
const handleSignIn = async () => {
  if (loading.value) return;
  loading.value = true;

  try {
    const res = await loginApi.signInApi({});
    if (res?.code === 1) {
      uni.showToast({
        title: '签到成功',
        icon: 'success'
      });
      // 延迟关闭弹窗
      setTimeout(() => {
        uni.navigateBack(); // 返回上一个页面(即关闭弹窗)
      }, 800);
    } else {
      uni.showToast({
        title: res?.msg || '签到失败,请稍后再试',
        icon: 'none'
      });
    }
  } catch (err) {
    console.error('签到请求失败:', err);
    uni.showToast({
      title: '网络异常,请稍后再试',
      icon: 'none'
    });
  } finally {
    loading.value = false;
  }
};
相关推荐
摸着石头过河的石头2 小时前
Service Worker 深度解析:让你的 Web 应用离线也能飞
前端·javascript·性能优化
用户4099322502122 小时前
Vue 3中watch侦听器的正确使用姿势你掌握了吗?深度监听、与watchEffect的差异及常见报错解析
前端·ai编程·trae
1024小神2 小时前
Xcode 常用使用技巧说明,总有一个帮助你
前端
molly cheung2 小时前
Vue3:watch与watchEffect的异同
vue.js·watch·store·watcheffect
政采云技术2 小时前
音视频通用组件设计探索和应用
前端·音视频开发
Hilaku3 小时前
我用AI重构了一段500行的屎山代码,这是我的Prompt和思考过程
前端·javascript·架构
IT_陈寒3 小时前
Vite性能优化实战:5个被低估的配置让你的开发效率提升50%
前端·人工智能·后端
IT_陈寒3 小时前
Java性能调优的7个被低估的技巧:从代码到JVM全链路优化
前端·人工智能·后端
掘金安东尼4 小时前
前端周刊第439期(2025年11月3日–11月9日)
前端·javascript·vue.js