前端伪进度条实现(仿antd message使用react组件静态方法)

news2024/12/25 12:57:43

文章目录

  • 背景
  • 实现方法
    • (一) react组件静态方法
    • (二) 通过静态方法改变组件的状态
    • (三) 指定进度条的步幅规则
    • (四) 成功和失败的状态改变
      • 1. 成功
      • 2. 失败
    • (五) 组件消失
    • (六) 背景遮罩
  • 最终实现及代码
    • 组件代码
    • 模拟调用进度条组件的代码
  • 可能遇到的问题
    • 静态方法调不到/报错
    • 组件渲染两次

背景

react项目中, 有些页面加载很慢, 为了提升用户体验, 需要在前端做一个伪进度条, 并且把这个伪进度条封装成一个组件, 提供给多个项目使用.

这个伪进度条有以下特点:

  1. 基于antd组件进行二次开发. 利用 antd 的 Spin, Progress 组件开发, 减少工作量.
  2. 在进度条走到 99% 的时候会卡住, 等拿到响应的时候完成.
  3. 考虑到要把这个伪进度条封装成组件, 所以最好是用类似 message.info() 这种方法调用, 不然不好对响应之后的组件状态进行改变. 因此要用到react组件的静态方法.
  4. 我用的函数组件 (当然用类组件也是可以的).

实现方法

(一) react组件静态方法

这种方式感觉平常开发很少用到, 放一个 gpt 给的示例:

React组件中使用静态方法可以有多种方式。下面是一个使用静态方法的React组件示例:

import React from 'react';

class MyComponent extends React.Component {
  static myStaticMethod() {
    console.log('This is a static method.');
  }

  render() {
    return (
      <div>
        {/* 组件内容 */}
      </div>
    );
  }
}

// 在其他地方调用静态方法
MyComponent.myStaticMethod();

export default MyComponent;

在上面的代码中,myStaticMethod是一个静态方法,可以直接通过组件类名调用,例如MyComponent.myStaticMethod()。

请注意,在React组件的静态方法中,无法访问组件的实例属性或实例方法,因为静态方法是属于类本身的,而不是实例。

另外,你也可以使用ES6的类静态属性语法来定义静态方法:

import React from 'react';

class MyComponent extends React.Component {
  static myStaticMethod = () => {
    console.log('This is a static method.');
  }

  render() {
    return (
      <div>
        {/* 组件内容 */}
      </div>
    );
  }
}

// 在其他地方调用静态方法
MyComponent.myStaticMethod();

export default MyComponent;

以上是在类声明中定义的静态方法,也可以在函数式组件中使用静态方法。下面是一个函数式组件中使用静态方法的示例:

import React from 'react';

function MyFunctionalComponent() {
  return (
    <div>
      {/* 组件内容 */}
    </div>
  );
}

MyFunctionalComponent.myStaticMethod = () => {
  console.log('This is a static method.');
};

// 在其他地方调用静态方法
MyFunctionalComponent.myStaticMethod();

export default MyFunctionalComponent;

我习惯用函数组件, 所以采用了函数组件的静态方法写法.
再加上使用了 antd 的 Spin 和 Progress 组件, 得到了下面的组件代码:

import React,{useState,useEffect,memo} from 'react';
import {Progress,Spin} from 'antd';
import './index.css'

const SelfDevProgress = (props)=> {
    return(
        <div className='outer'>
            <div className='inner'>
                <p>系统正在全力加载中, 请稍后...</p>
                <Spin />
                <Progress percent={70} status={"active"}/>
            </div>
        </div>
    )
}

// 静态调用方式
SelfDevProgress.success = (message) => {
    console.log(message,"success")
}

export default SelfDevProgress;

外部调用:

import React from 'react';
import SelfDevProgess from "./modules/selfDevProgess"

const Main = () => {
    SelfDevProgess.success("成功提示")
    return(
        <div>
            <p>模块组件页面testtest父页面</p>
            {/* <SelfDevProgess time={5}/> */}
        </div>
    )
}

export default Main;

css 文件:

.outer {
}
.inner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  width: 60%;
  text-align: center;
}

但这时候, 只能知道静态方法调用成功了, 没法通过静态方法去改变组件的状态, 比如进度条的 percent 和 status , 我尝试在静态方法里调用 SelfDevProgress(percent:100) 这种方式去传值, 会报错.

(二) 通过静态方法改变组件的状态

改变状态需要借助另外一个函数来实现, 写一个 SelfDevProgressAPI 函数, 让它来作为一个中转站.

这个函数的作用是:

1. 允许在静态方法里调用, 接收父组件调用的时候传过来的参数, 并对这些参数进行处理;
2. 创建div, 把之前写的 SelfDevProgess 组件的html元素挂载到这个div上, 让组件的html通过这个div展示出来;

注意:
1. 必须给挂载的div设置一个唯一的id, 如果不给设置一个唯一的id,每次调用都会挂载一个div,这个div会重叠很多次;
2. 这个方法里面是不能用 return 这种方式去展示的, 要用 ReactDom.render( )这种方式挂载; 如果 ReactDom 报错的话, 要引入一下ReactDOM.

import ReactDOM from 'react-dom';

ReactDOM.render 是 React 的最基本方法用于将模板转为 HTML 语言,并插入指定的 DOM 节点。ReactDOM.render(template,targetDOM) 方法接收两个参数:

  • 第一个是创建的模板,多个 dom 元素外层需使用一个标签进行包裹,如 <div>
  • 第二个参数是插入该模板的目标位置。
const SelfDevProgressAPI = (type) => {
    const per = (type="success") ? 100 : 70

    // 创建一个div,把它挂载到body元素的下面(因为这个进度条是相对于整个页面的)
    // 如果不给设置一个唯一的id,每次调用都会挂载一个div,这个div会重叠很多次
    let container = document.querySelector('#selfDevProgress-container');
    if (!container) {
        container = document.createElement('div');
        container.id = 'selfDevProgress-container';
        document.body.appendChild(container);
      }

    // react17的写法, 把组件渲染到刚刚创建的div上
    ReactDOM.render(
        <SelfDevProgress percent={per}/>,
        container
      );
    // 注意这个方法里面是不能用return这种方式去展示的
    // return(
    //     <div>
    //         <SelfDevProgress percent={per}/>
    //     </div>
    // )
}

// 静态调用方式
SelfDevProgress.success = (message) => {
    console.log(message,"success")
    SelfDevProgressAPI("success")
}

(三) 指定进度条的步幅规则

这个可以自由指定, 但是要注意几点:

1. 最好不要出现小数的步幅, 小数出现在进度条上有点不太好看;
2. 在最后的时候要有卡顿, 比如说从90%的时候开始走的变慢, 或者卡在99%的位置;

以下是我指定的一些规则:

进度条时间(duration)规则定时器时间间隔步幅(s)
//100ms默认为2
duration > 10 秒10s走到99%, 然后等待100ms1
10 >= duration > 55s走到98%, 这时候将步幅改为 1, 走到99%等待100ms2
5 >= duration > 22s走到95%, 这时候将步幅改为 1, 走到99%等待100ms5
duration <=21s走到90%, 这时候将步幅改为 1, 走到99%等待100ms10
 /* 进度条展示规则 
        如果没有设置duration,就按 5s 处理
        1.duration > 10 秒, 10s走到99%,然后等待
        2.10 >= duration > 5, 5s走到98%, 这时候将步幅改为 1, 走到99%等待
        3.5 >= duration > 2, 2s走到95%, 这时候将步幅改为 1, 走到99%等待
        4.duration <=2, 1s走到90%, 这时候将步幅改为 1, 走到99%等待
*/

(四) 成功和失败的状态改变

1. 成功

成功比较简单, 成功状态之前让进度条卡在99%, 成功时需要:

(1) 将进度条状态跳到 100%
(2) 进度条状态改为 success 成功状态 (变为绿色)
(3) 改变 loading 图标的状态
(4) 清除定时器
(5) 进度条整个消失

2. 失败

失败时需要:

(1) 进度条卡在目前的数值
(2) 进度条状态改为 exception 失败状态 (变为红色)
(3) 改变 loading 图标的状态
(4) 清除定时器
(5) 进度条整个消失

这里面第一步将 “进度条卡在目前的数值” 容易遇到问题. 比如: 在调用clearInterval()之后,setInterval()循环仍在运行, 进度条会在变红的情况下继续前进.

解决方法可以查看: 调用clearInterval(), 定时器仍在进行

(五) 组件消失

首先想到的是设置 display:"none" 这种方式, 但是感觉有点太生硬了, 唰的一下就突然消失了, 所以想给加一个过渡.

试了一下将 width 和 height 设为 0 不太好使, 最后的实现方法是: "结束的时候改变透明度, 从1到0, 用 transition 加一个过渡动画, 当透明度为 0 的时候, 再将 display 设为 none.

至于进度条出现的时候要不要采用渐进的方式, 我觉得没有必要, 所以就没有加.

    // 控制进度条整个组件是否展示
    const isShow = (state) => {
        let container = document.querySelector('#selfDevProgress-container');
        if(state) {
            container.style.display = "block"
            container.style.opacity = "1"
        } else {
            let t1 = setTimeout(() => {
                container.style.transition = "opacity 0.5s ease-out"
                container.style.opacity = "0"
                let t2 = setTimeout(() => {
                    container.style.display = "none"
                    clearTimeout(t2)
                }, 500);
                clearTimeout(t1)
            }, 500);
            
        }
    }

效果是这样的:

进度条组件消失视频

(六) 背景遮罩

遮罩思路:

  1. #selfDevProgress-container 中利用 position 属性定义好位置, 以及设置好宽高 (因为这个进度条组件是相对于整个页面的, 所以这个div应该覆盖整个可视页面);

  2. #self-dev-outer 中继承父组件的宽高, 利用背景色透明度来加遮罩;

在这里插入图片描述

最终实现及代码

整个工程压缩包已上传资源.

demo中涉及到的几个文件的结构:

在这里插入图片描述

组件代码

index.jsx:

import React,{useState,useEffect} from 'react';
import ReactDOM from 'react-dom';
import {Progress,Spin} from 'antd';
import './index.css'

const SelfDevProgress = (props)=> {
    const {percent,duration,msg,mask} =  props;
    console.log("mask",mask)

    const [getChangePer,setGetChangePer] = useState(percent)
    const [perStatus,setPerStatus] = useState("active")
    const [timer,setTimer] = useState(null) // 定时器

    let s = 2 ; // 进度条步幅,默认为2 (5s)
    // let timer = null; // 定时器

     /* 进度条展示规则 
        如果没有设置duration,就按 5s 处理
        1.duration > 10 秒, 10s走到99%,然后等待
        2.10 >= duration > 5, 5s走到98%, 这时候将步幅改为 1, 走到99%等待
        3.5 >= duration > 2, 2s走到95%, 这时候将步幅改为 1, 走到99%等待
        4.duration <=2, 1s走到90%, 这时候将步幅改为 1, 走到99%等待
    */
    const rule = () => {
        switch (true) {  // 这个switch里面是不能写duration的,否则会失效
            case duration > 10:
                s = 1
                break;
            case duration > 5 && duration <= 10:
                s = 2
                break;
            case duration > 2 && duration <= 5:
                s = 5
                break;
            case duration <= 2:
                s = 10
                break;
            default:
                break;
        }
    }

    // 控制进度条整个组件是否展示
    const isShow = (state) => {
        let container = document.querySelector('#selfDevProgress-container');
        if(state) {
            container.style.opacity = "1"
            container.style.display = "block"
        } else {
            let t1 = setTimeout(() => {
                container.style.transition = "opacity 1s ease-out"
                container.style.opacity = "0"
                let t2 = setTimeout(() => {
                    container.style.display = "none"
                    clearTimeout(t2)
                }, 1000);
                clearTimeout(t1)
            }, 500);
            
        }
    }

    // 控制进度条组件上面的loading标识
    const msgSpin = (state) => {
        const spin = document.querySelector('#self-dev-spin')
        if(!state) {
            spin.style.visibility = "hidden"
        } else {
            spin.style.visibility = "visible"
        }
    }

    // 调起进度条
    const initial = async () => {
        // 判断是否有遮罩
        let outer = document.querySelector('#self-dev-outer');
        if(mask) {
            outer.style.backgroundColor = 'rgba(255,255,255,0.7)'
        } else {
            outer.style.backgroundColor = 'unset'
        }
        // 获得进度条步幅
        await rule()
        // 显示进度条
        isShow(true)
        // 改变进度条状态
        msgSpin(true)
        setPerStatus("active")
        // 进度条步数
        let per = 0
        setGetChangePer(per)
        let t = setInterval(() => {          
            per += s
            if(per === 99) { // 在100之前要卡住停顿
                clearInterval(t)
            }
            if(per + s >= 100) { // 最后一段改变步幅
                s = 1
            }
            setGetChangePer(per)
        }, 100);
        setTimer(t)
    }

    // 响应成功
    const success = () => {
        // 清除定时器
        clearInterval(timer) 
        // 改变进度条状态
        setGetChangePer(100)
        setPerStatus("success")
        // 改变图标
        msgSpin(false)
        // 进度条消失
        isShow(false)
    }

    // 响应失败
    const fail = () => {
        // 清除定时器
        clearInterval(timer) 
        // 改变进度条状态
        setPerStatus("exception")
        // 改变图标
        msgSpin(false)
        // 进度条消失
        isShow(false)
    }

    useEffect(()=>{
        switch (percent) {
            case 0:
                initial()
                break;
            case 100 :
                success()
                break;
            case 50:
                fail()
                break;
            default:
                break;
        }
    },[percent])

    return(
        <div id='self-dev-outer'>
            <div className='self-dev-inner'>
                <p id='self-dev-msg'>{msg}</p>
                <Spin id='self-dev-spin'/>
                <Progress percent={getChangePer} status={perStatus}/>
            </div>
        </div>
    )
    
}

const SelfDevProgressAPI = ({type,mask,msg,duration}) => {
    let per = 0

    switch (type) {
        case "start":
            per = 0
            break;
        case "success":
            per = 100
            break;
        case "fail":
            per = 50
            break;
        default:
            break;
    }

    // 创建一个div,把它挂载到body元素的下面(因为这个进度条是相对于整个页面的)
    let container = document.querySelector('#selfDevProgress-container');
    if (!container) {
        container = document.createElement('div');
        container.id = 'selfDevProgress-container';
        document.body.appendChild(container);
      }

    // react 17 写法, 把组件渲染到刚刚创建的div上
    ReactDOM.render(
        <SelfDevProgress percent={per} duration={duration} msg={msg} mask={mask}/>,
        container
      );
}

// 静态调用方式
/*
    duration: 进度条持续的时间(number)
    msg: 成功或失败的文字提示(string)
    mask: 是否有遮罩(Boolean)
    steps:步骤(array)这个参数暂时没用到
*/
SelfDevProgress.start = (mask,duration,msg) => {
    let obj = {
        type:"start",
        mask: mask===undefined ? false : mask,
        msg: msg ? msg : "系统正在全力加载中, 请稍后...",
        duration: duration ? duration : 4,
    }
    SelfDevProgressAPI(obj)
}
SelfDevProgress.success = (msg) => {
    let obj = {
        type:"success",
        msg: msg ? msg : "加载成功",
    }
    SelfDevProgressAPI(obj)
}
SelfDevProgress.fail = (msg) => {
    let obj = {
        type:"fail",
        msg: msg ? msg : "加载失败",
    }
    SelfDevProgressAPI(obj)
}

export default SelfDevProgress;

index.css 代码:

#selfDevProgress-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
#self-dev-outer {
  width: 100%;
  height: 100%;
}
.self-dev-inner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  width: 60%;
  text-align: center;
  z-index: 99;
}

模拟调用进度条组件的代码

import React from 'react';
import SelfDevProgess from "./modules/selfDevProgess"
import './main.css'

const Main = () => {
    let t0 = setTimeout(() => {
        SelfDevProgess.start()
        clearTimeout(t0)
    }, 2000);
    let t1 = setTimeout(() => {
        // SelfDevProgess.fail()
        SelfDevProgess.success()
        clearTimeout(t1)
    }, 5000);
    return(
        <div>
            <p className='fa'>模块组件页面testtest父页面</p>
        </div>
    )
}

export default Main;

可能遇到的问题

静态方法调不到/报错

要注意静态方法写的位置, 比如像下面这个 demo 中, 静态方法书写的位置是在 SelfDevProgress 方法外面, export default SelfDevProgress; 之前的.
如果写在 SelfDevProgress 方法内部, 就会报错.

import React,{useState,useEffect,memo} from 'react';
import ReactDOM from 'react-dom';
import {Progress,Spin} from 'antd';
import './index.css'

const SelfDevProgress = (props)=> {
    const [percent,setPersent] = useState(props.per ? props.per : 0)
    const [perStatus,setPerStatus] = useState("active")

    return(
        <div className='outer'>
            <div className='inner'>
                <p>系统正在全力加载中, 请稍后...</p>
                <Spin />
                <Progress percent={percent} status={perStatus}/>
            </div>
        </div>
    )
    
}

// 静态调用方法书写的位置
SelfDevProgress.success = (message) => {
    console.log(message,"success")
}

export default SelfDevProgress;

组件渲染两次

写到一半打印的时候发现, 组件渲染了两次, 但是我只调用了一次, 截图如下:

在这里插入图片描述

于是上网搜索, 发现是react严格模式的问题, 把它注释掉就好了.
原贴: 【React】- 组件生命周期连续渲染两次问题

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1136227.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

23款奔驰GLC260L升级原厂 360全景影像 新款透明底盘

360全景影像影像系统提升行车时的便利&#xff0c;不管是新手或是老司机都将是一个不错的配置&#xff0c;无论是在倒车&#xff0c;挪车以及拐弯转角的时候都能及时关注车辆所处的环境状况&#xff0c;避免盲区事故发生&#xff0c;提升行车出入安全性。Xjh15863 360全景影像…

【超参数研究01】使用网格搜索优化超参数

一、说明 在神经网络训练中&#xff0c;超参数也是需要优化的&#xff0c;然而在超参数较多&#xff08;大于3个&#xff09;后&#xff0c;如果用穷举的&#xff0c;或是通过经验约摸实现就显得费时费力&#xff0c;无论如何&#xff0c;这是需要研究、规范、整合的要点&#…

漏洞复现--用友U8-Cloud upload.jsp任意文件上传

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

分享一下怎么做多门店商城系统

随着互联网的快速发展&#xff0c;传统实体店面临着巨大的挑战。为了更好地适应市场变化&#xff0c;提高竞争力&#xff0c;多门店商城系统应运而生。这种新型的商业模式&#xff0c;旨在通过线上线下融合&#xff0c;实现门店之间的互联互通&#xff0c;提高运营效率&#xf…

云尘靶场-铁三域控

第一次 通过vpn链接 然后fscan扫描c段 扫描出来三个ip存活 并且141存在永恒之蓝 我们看看能不能直接复现 按照原本的设置发现 提示这里需要通过32位来进行 那我们开始设置 利用MS17-010渗透win7&#xff08;32位&#xff09;_利用ms17-010渗透win7(32位)-CSDN博客 https:…

外汇天眼:MT4白标与MT5,谁更适合如今的外汇市场?

2017年4月&#xff0c;外汇市场因迈达克的官宣闹得沸沸扬扬。 俄罗斯知名软件提供商迈达克&#xff08;MetaQuotes&#xff09;宣布停止出售旗下产品MT4的主标业务&#xff0c;意在淘汰MT4软件&#xff0c;转而主推MT5平台。 对于计划成为经纪商的人来说&#xff0c;是选择快速…

个人记账理财软件 Money Pro mac中文版软件介绍

Money Pro for mac是一款综合性高的理财工具&#xff0c;Money Pro是一套能够协同工作的工具&#xff0c;可用来追踪账户、管理账单以及制作预算&#xff0c;您可以为每个时间段设置不同的预算限值。财务一切尽在掌控之中。 Money Pro for mac软件介绍 Money Pro for mac提供一…

常见深度学习目标检测指标 AP mAP mAP@0.5 mAP@0.5:0.95 简短总结

目标检测指标计算 准确率 召回率 AP mAP 1.准确率与召回率 TP 真正例 将正类预测为正类数 FP 假正例 将负类预测为正类数 误检 TN 真负例 将负类预测为负类 FN 假负例 将正类预测为负类 漏检 2.AP 通常情况下 P与R成反比 因此为了更好的衡量模型 引入 AP mAP AP为…

学会场景提问,让AI“小助手”为我所用

文章目录 一、故事叙述提问举例 二、产品描述提问举例 三、报告撰写提问举例 四、邮件和信件撰写提问举例 五、新间稿和公告撰写提问举例 六、学术论文和专业文章撰写提问举例 我们知道AI技术不仅能够自动生成文章和内容&#xff0c;还可以根据我们的需求提供创意灵感和解决问题…

uni-app配置微信开发者工具

一、配置微信开发者工具路径 工具->设置->运行配置->小程序运行配置->微信开发者工具路径 二、微信开发者工具开启服务端口

OpenWRT软路由web界面如何远程访问?

文章目录 1.openWRT安装cpolar2.配置远程访问地址3.固定公网地址 简单几步实现在公网环境下远程访问openWRT web 管理界面&#xff0c;使用cpolar内网穿透创建安全隧道映射openWRT web 界面面板443端口&#xff0c;无需公网IP&#xff0c;无需设置路由器。 1.openWRT安装cpola…

buuctf[强网杯 2019]随便注 1(超详细,三种解法)

第一种解法 堆叠注入 网页环境判断是否是字符型注入1判断是否存在关键字过滤select联合查询被过滤&#xff0c;只能用堆叠注入了查看有几个字段1 order by 2#正常回显1 order by 3#回显报错&#xff0c;可以看出只有两个字段查看所有数据库1; show databases;查看所有数据表1;…

python,pandas ,openpyxl提取excel特定数据,合并单元格合并列,设置表格格式,设置字体颜色,

python&#xff0c;pandas &#xff0c;openpyxl提取excel特定数据&#xff0c;合并单元格合并列&#xff0c;设置表格格式&#xff0c;设置字体颜色&#xff0c; 代码 import osimport numpy import pandas as pd import openpyxl from openpyxl.styles import Font from op…

数字音频工作站软件 Ableton Live 11 mac中文软件特点与功能

Ableton Live 11 mac是一款数字音频工作站软件&#xff0c;用于音乐制作、录音、混音和现场演出。它由Ableton公司开发&#xff0c;是一款极其流行的音乐制作软件之一。 Ableton Live 11 mac软件特点和功能 Comping功能&#xff1a;Live 11增加了Comping功能&#xff0c;允许用…

详解:飞讯是如何助力集团型制造企业实现数字化转型的

飞讯软件成立17年来&#xff0c;成功服务了上百家自动化装备及零部件制造企业&#xff0c;对这类企业的业务特点和痛点非常熟悉。在解决企业数字化转型挑战方面&#xff0c;我们拥有丰富的经验和技术平台优势。因此&#xff0c;于2022年我们与东莞一家大型自动化装备制造企业正…

Fuzz测试:自动化测试软件隐患和漏洞的秘密武器

0x01 什么是模糊测试 模糊测试&#xff08;Fuzz Testing&#xff09;是一种广泛用于软件安全和质量测试的自动化测试方法。它的基本思想是向输入参数或数据中注入随机、不规则或异常的数据&#xff0c;以检测目标程序或系统在处理不合法、不正常或边缘情况下的行为。模糊测试通…

Egg.js使用MySql数据库

最近在接手一个项目&#xff0c;vuenuxtegg&#xff0c;我也是刚开始学习egg.js&#xff0c;所以会将自己踩的坑都记录下来。 安装mysql 使用sequelize连接数据库&#xff0c;首先安装egg-sequelize和mysql2。 npm install --save egg-sequelize mysql2打开package.json文件…

优思学院|中质协六西格玛考试形式是什么样的?

中质协的考试形式主要为单选和多选题&#xff0c;近年也有加了一小部分填空题&#xff0c;和国际认证考试有很大区别&#xff0c;因为美质协&#xff08;ASQ&#xff09;、国际精益六西格玛研究所&#xff08;ILSSI&#xff09;&#xff0c;又或者著名的PMP项目管理认证等都是采…

day51 --动态规划10

121. 买卖股票的最佳时机 122.买卖股票的最佳时机II 第一题&#xff1a;买卖股票的最佳时机 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出…

Phthon下载库函数

在代码中使用import tushare as ts导入时编译会报错找不到tushare&#xff0c;此时则表示本地没有相应的库函数包 打开安装python的目录&#xff0c;找到pip.exe文件目录&#xff0c;例如D:\Python\Python311\Scripts&#xff0c;文件夹右键->在终端打开&#xff0c;输入pi…