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

文章目录

  • 背景
  • 实现方法
    • (一) 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】- 组件生命周期连续渲染两次问题

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

帆软report JS实现填报控件只能填写一次

效果 方法&#xff1a; 代码&#xff1a; if(this.getValue()!"")//判断这个控件框是否有值&#xff0c;这里是不为空{this.setEnable(false)}//不为空&#xff0c;则不能再修改else{this.setEnable(true)}//为空&#xff0c;可以编辑

Perl爬虫程序

以下是一个使用Perl爬虫程序&#xff0c;用于爬取图像。每行代码的中文解释如下&#xff1a; #!/usr/bin/perl ​ use strict; use warnings; use Mojo::UserAgent; use JSON; ​ # 创建一个Mojo::UserAgent实例 my $ua Mojo::UserAgent->new; ​ # 使用获取代理 my $prox…

计算机网络重点概念整理-第三章 数据链路层【期末复习|考研复习】

第三章 数据链路层 【期末复习|考研复习】 计算机网络系列文章传送门&#xff1a; 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称&缩写 文章目录 第三章 数据链路层 【期末复习…

两数和的目标 python (初学者vs程序员)

题目描述 1&#xff09;给定一个整数列表&#xff0c;在列表中&#xff0c;从前向后查找两个元素使其相加之和等于目标数&#xff0c;并返回两个整数在列表中的下标。如果没有符合条件的数字&#xff0c;输出False&#xff0c;本题假设题目的解唯一。‬‪‬‪‬‪‬‪‬‮‬‪…

AT32固件库外设使用,ArduinoAPI接口移植,模块化

目录 一、ArduinoAPI移植一、通用定时器使用1.计时1.2.ETR外部时钟计数4.ArduinoAPI - timer 三、ADC1.ADC初始化&#xff08;非DMA&#xff09;2.ADC_DMA 规则通道扫描 六、USB HID IAP1.准备好Bootloader和app2.配置好时钟&#xff0c;一定要打开USB3.将生成的时钟配置复制到…

《Attention Is All You Need》阅读笔记

论文标题 《Attention Is All You Need》 XXX Is All You Need 已经成一个梗了&#xff0c;现在出现了很多叫 XXX Is All You Need 的文章&#xff0c;简直标题党啊&#xff0c;也不写方法&#xff0c;也不写结果&#xff0c;有点理解老师扣论文题目了。 作者 这个作者栏太…

vue源码分析(五)——vue render 函数的使用

文章目录 前言一、render函数1、render函数是什么&#xff1f; 二、render 源码分析1.执行initRender方法2.vm._c 和 vm.$createElement 调用 createElement 方法详解&#xff08;1&#xff09;区别&#xff08;2&#xff09;代码 3、原型上的_render方法&#xff08;1&#xf…

视频特效制作软件 After Effects 2023 mac中文版介绍说明

After Effects 2023 mac是一款专业视频特效和动态图形设计软件。ae2023被广泛应用于电影、电视节目、广告和网络媒体等领域&#xff0c;可以创建各种令人惊叹的视觉效果。 在After Effects 2023中&#xff0c;用户可以使用强大的工具和功能来制作复杂的特效和动画。新版本引入了…

数据库简史:多主数据库架构的由来和华为参天引擎的机遇

注&#xff1a;本文发表后&#xff0c;收到了很多后台反馈&#xff0c;其中关于大型机的早期成就不容省略。微调重发本文&#xff0c;纯属个人观点&#xff0c;错谬之处&#xff0c;仍然期待指正。 2023年10月13日&#xff0c;在北京举办的“2023金融业数据库技术大会"上&…

GPT的广泛应用会对互联网公司造成挑战吗?——探讨GPT在实际使用中的应用和影响

文章目录 前言GPT 技术的背景和发展历程GPT 技术对互联网行业的影响GPT 技术在互联网行业中的应用GPT 技术对于用户隐私和数据安全的威胁GPT 技术对于人类工作岗位的影响加强 AI 伦理和监管加强 AI 安全性和隐私保护推动 AI 创新和发展&#xff0c;避免过度依赖 AIGPT 技术是一…

HIT_OS_LAB1 调试分析 Linux 0.00 引导程序

操作系统实验一 姓名&#xff1a;董帅学号&#xff1a;2021111547班级&#xff1a;21R0312 1.1 实验目的 熟悉实验环境掌握如何手写Bochs虚拟机的配置文件掌握Bochs虚拟机的调试技巧掌握操作系统启动的步骤 1.2 实验内容 1.2.1 掌握如何手写Bochs虚拟机的配置文件 boot: f…

2.MySQL的调控按钮——启动选项和系统变量

2.MySQL的调控按钮——启动选项和系统变量 1.启动选项和配置文件1.1 在命令行上使用选项1.2 配置文件中使用选项1.2.1 配置文件路径1.2.2 配置文件的内容1.2.3 特定 MySQL 版本的专用选项组1.2.4 配置文件的优先级1.2.5 同一个配置文件中多个组的优先级1.2.6 defaults-file 的使…

回归预测 | MATLAB实现BO-BiLSTM贝叶斯优化双向长短期神经网络多输入单输出回归预测

回归预测 | MATLAB实现BO-BiLSTM贝叶斯优化双向长短期神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现BO-BiLSTM贝叶斯优化双向长短期神经网络多输入单输出回归预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 基本介绍 MATLAB实现BO-BiLSTM贝叶斯优化双向长…

mysql源码安装

Linux环境 1、mysql下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/5.7.html#downloads 下载参考&#xff1a; 2、把下载的 MySQL 压缩包上传到 Linux 服务器 3、解压mysql-5.7.39-linux-glibc2.12-x86_64.tar.gz tar -zxvf mysql-5.7.39-linux-glibc2.12-x86…

【Linux】解决缓存锁问题:无法获得锁 /var/lib/dpkg/lock-frontend

今天在运行apt-get update更新软件包后&#xff0c;突然发现安装新的软件出现了这个报错&#xff1a;正在等待缓存锁&#xff1a;无法获得锁 /var/lib/dpkg/lock-frontend。锁正由进程 1855&#xff08;unattended-upgr&#xff09;持有。如图。 这个错误通常是由于其他进程正在…

Word批量删除文档属性和个人信息方法图解

投标文件中设计敏感信息&#xff0c;在投标前必须删除&#xff0c;Word批量删除文档属性和个人信息方法图解&#xff1a; 右键word文件属性--详细信息&#xff0c;可以查看如下信息&#xff1b; 删除上述信息的办法&#xff1a; 1.打开word文件---文件 2.检查文档、检查文档 检…

竞赛 深度学习卫星遥感图像检测与识别 -opencv python 目标检测

文章目录 0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **深度学习卫星遥感图像检测与识别 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐…

Linux操作系统 - 从概念上认识进程

目录 前置知识 冯诺依曼和现代计算机结构 操作系统的理解 进程的概念 进程和PCB 查看进程信息的指令 - ps 进程的一些特性 进程标识符 - PID 进程状态 进程状态的概念 Linux下的进程状态 父子进程 子进程的创建 - fork 僵尸进程 孤儿进程 进程切换 CPU上下文切…

分享54个ASP.NET源码总有一个是你想要的

分享54个ASP.NET源码总有一个是你想要的 链接&#xff1a;https://pan.baidu.com/s/1khPzxtOFP0wUHpg7TBDitg?pwd8888 提取码&#xff1a;8888 项目名称 (ASP.Net)基于三层架构的企业信息管理系统 asp .net mvc编写的房产管理系统 asp.net core mvc 病人管理后台 asp.ne…

【表面缺陷检测】钢轨表面缺陷检测数据集介绍(2类,含xml标签文件)

一、介绍 钢轨表面缺陷检测是指通过使用各种技术手段和设备&#xff0c;对钢轨表面进行检查和测量&#xff0c;以确定是否存在裂纹、掉块、剥离、锈蚀等缺陷的过程。这些缺陷可能会对铁路运输的安全和稳定性产生影响&#xff0c;因此及时进行检测和修复非常重要。钢轨表面缺陷…