2022-12-27 工作记录--React-使用antd-mobile实现圆弧倒计时

React-使用antd-mobile实现圆弧倒计时

一、实现效果

请添加图片描述

二、实现代码

请添加图片描述

1、antd-mobile官网

https://mobile.ant.design/zh/components/progress-circle

2、安装antd-mobile

npm i antd-mobile

或者

yarn add antd-mobile

3、检查package.json里是否安装成功

在这里插入图片描述

4、对应代码

实现步骤:

  • 【1】、自定义state
    • realTime:实际倒计时时间
    • circlePercentage:滚动圈滚动百分比
  • 【2】、初始化定时器为null
  • 【3】、在componentDidMount里处理倒计时【注意:先关闭倒计时,再调用倒计时方法,是为了实现:每次进入页面,就让倒计时重新计时】;
  • 【4】、倒计时样式渲染:通过antd-mobile里的ProgressCircle实现;
  • 【5】、在componentWillUnmount里清除倒计时;
  • 【6】、处理特殊情况 —— ios缓存情况:ios返回页面时不会默认刷新页面,即不会进componentDidMount

page_answer.jsx

import React from 'react';
import answerStore from '@src/store/answer'; // 引入answerStore【answerStore相关的是我项目接口相关的内容和公用方法,小萝卜儿们可根据实际情况处理】
import { ProgressCircle } from 'antd-mobile'; // 【4】引入 进度圈
import './page_answer.less'; // 引入css

class Page_answer extends React.Component {
  constructor(props) {
    super(props);
  }

  // 【1】、自定义state
  state = {
    realTime: 0, // 实际倒计时时间
    circlePercentage: 0, // 滚动圈滚动百分比
  }

  // 【2】、初始化定时器为null
  timer = null; // 定时器

  async componentDidMount() {
    // async...await...表示先请求接口数据、渲染html
    await answerStore.getQuestion(); // 请求接口-获取题目

    /** 【3】用户从其他链接返回活动页面,倒计时重新计时 */
    clearInterval(this.timer);
    this.countDown();

    // 【6】处理特殊情况 —— ios缓存情况。监听页面展示-针对情况:返回时页面为缓存而非刷新【缓存: 即页面未刷新、未调用接口请求数据】
    const isIos = /ipad|iPhone|Mac/i.test(window.navigator.userAgent);
    if (isIos) { // ios
      window.addEventListener('pageshow', this.iosPageShow.bind(this), this);
    } else { // Android
      document.addEventListener("visibilitychange", this.androidPageShow.bind(this), this);
    }
  }

  componentWillUnmount() {
    // 【5】清除定时器
    clearInterval(this.timer); 

    // 【6】处理特殊情况 —— ios缓存情况。
    window.removeEventListener('pageshow', this.iosPageShow.bind(this), this);
    document.removeEventListener("visibilitychange", this.androidPageShow.bind(this), this);
  }

  // 【6】ios下的页面展示
  iosPageShow = () => {
    console.info('ios visible');
    // 在这儿写下缓存情况时 页面展示后需要进行的操作~【我封装成了一个函数,直接写到该函数里即可】
    this.pageShow();
  }

  // 【6】android下的页面展示
  androidPageShow = () => {
    if (window.visibilityState === "visible") {
      console.info('android visible');
      // 在这儿写下缓存情况时 页面展示后需要进行的操作~【我封装成了一个函数,直接写到该函数里即可】
      this.pageShow();
    }
  }

  // 【6】封装函数-页面展示
  pageShow = async (show) => {
    if (show) {
      console.info('visible');
      // async...await...表示先请求接口数据、渲染html
      await answerStore.getQuestion(); // 请求接口-获取题目

      /** 用户从其他链接返回活动页面,倒计时重新计时 */
      const {
        // 倒计时时间
        realTime
      } = this.state;
      const {
        // 本题是否已经回答过了
        answered
      } = answerStore?.questionInfo || {};
      // 清除定时器
      clearInterval(this.timer);
      // 当倒计时时间不为0 且 本题未回答过,从其他页面返回,会重新倒计时
      realTime != 0 && !answered && this.countDown();
    }
  }

  // 【3】倒计时
  countDown = () => {
    const { answerLimitTime } = answerStore?.questionInfo || {}; // 后端返的倒计时数据(单位: 毫秒)
    const gotRealTime = (answerLimitTime * 1) / 1000; // 前端实际获取到的倒计时秒数
    console.log('gotRealTime', gotRealTime);
    // 设置初始值
    this.setState({
      realTime: gotRealTime,
      circlePercentage: 0,
    })
    // 获取到滚动圈每次需自加的 滚动百分比
    const percentage = 100 / gotRealTime;

    // 先关闭倒计时
    clearInterval(this.timer);
    // 再定义倒计时
    this.timer = setInterval(() => {
      let { realTime } = this.state;
      if (realTime <= 0) {
        /** 倒计时结束 */
        // 关闭倒计时
        clearInterval(this.timer);
        // 让滚动圈滚动百分比、倒计时时间都归置为0
        this.setState({
          circlePercentage: 0,
          realTime: 0,
        })
        // 根据自己需求进行操作
        answerStore.submitAnswer('', false); // 调用接口-提交答案
        return;
      }
      // 时间每隔一秒减一秒 并 赋值到state里
      realTime--;
      this.setState({
        realTime,
        // 时间每隔一秒 滚动圈滚动百分比 自加 percentage
        circlePercentage: this.state.circlePercentage + percentage,
      })
      console.log('目前滚动圈百分比', this.state.circlePercentage);
    }, 1000)
  }

  render() {
    const {
      // 滚动圈滚动百分比
      circlePercentage,
      // 倒计时时间
      realTime,
    } = this.state;

    return (
      <div className="page_answer">
        {/* 【4】倒计时 */}
        <div className="box">
          <ProgressCircle percent={circlePercentage} style={{ '--track-width': `${10 * remScale}px`, '--size': `${103 * remScale}px`, '--fill-color': '#e2734b', '--track-color': '#fff' }}>{realTime}</ProgressCircle>
        </div>
      </div>
    );
  }
}
export default Page_answer;

page_answer.less

.box{
      width: 103px;
      height: 103px;
      position: relative;
      background-color: #fff;
      border-radius: 50%;
      left: 322px;
      top: 355px;
  }

哒哒哒哒~
请添加图片描述

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小呀小萝卜儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值