当前位置: 首页 > news >正文

【React】入门Day04 —— 项目搭建及登录与表单校验、token 管理、路由鉴权实现

项目搭建

  • 创建项目

    # 使用npx创建项目
    npx create-react-app my-react-app
    # 进入项目目录
    cd my-react-app
    # 创建项目目录结构
    mkdir -p src/{apis,assets,components,pages,store,utils}
    touch src/{App.js,index.css,index.js}
    • 使用npx create-react-app创建项目,进入项目目录后通过npm start启动。
    • 调整项目目录结构,包括apisassetscomponentspages等多个文件夹。
  • 使用技术

    • 接入scss预处理器,安装sass工具,创建全局样式文件index.scss
      # 安装sass工具
      npm i sass -D
      // 在src/index.scss中设置全局样式
      body {font-family: Arial, sans-serif;background-color: #f4f4f4;
      }
    • 引入组件库antd,安装后在Login页面测试Button组件。
      # 安装antd组件库
      npm i antd
      // 在src/pages/Login/index.jsx中使用Button组件
      import React from 'react';
      import { Button } from 'antd';const Login = () => {return (<div><Button type='primary'>登录</Button></div>);
      };export default Login;
    • 使用react-router-dom配置基础路由,创建LayoutLogin组件并配置路由规则。
      # 安装react-router-dom
      npm i react-router-dom
      // 在src/router/index.js中配置路由
      import { createBrowserRouter } from 'react-router-dom';
      import Login from '../pages/Login';
      import Layout from '../pages/Layout';const router = createBrowserRouter([{path: '/',element: <Layout />,},{path: '/login',element: <Login />,},
      ]);export default router;
    • 通过craco工具包配置别名路径,在craco.config.js中设置webpack别名,并在jsconfig.json中配置VsCode提示。
      # 安装craco工具包
      npm i @craco/craco -D
      // 在craco.config.js中配置别名
      const path = require('path');
      module.exports = {webpack: {alias: {'@': path.resolve(__dirname,'src')}}
      };
      // 在package.json中修改scripts命令
      "scripts": {"start": "craco start","build": "craco build","test": "craco test","eject": "react-scripts eject"
      }
      // 在src/router/index.js中使用别名
      import { createBrowserRouter } from 'react-router-dom';
      import Login from '@/pages/Login';
      import Layout from '@/pages/Layout';const router = createBrowserRouter([{path: '/',element: <Layout />,},{path: '/login',element: <Login />,},
      ]);export default router;
      // 在jsconfig.json中配置VsCode提示
      {"compilerOptions": {"baseUrl": "./","paths": {"@/*": ["src/*"]}}
      }

  • 功能模块实现

    • 登录模块

      • 基本结构搭建

  •         在Login/index.js创建登录页面结构,引入antd组件,使用@/assets路径引入图片,在Login/index.scss中设置样式。
  • import React from 'react';
    import { Card, Form, Input, Button } from 'antd';
    import logo from '@/assets/logo.png';
    import './index.scss';const Login = () => {return (<div className="login"><Card className="login-container"><img className="login-logo" src={logo} alt="" /><Form><Form.Item><Input size="large" placeholder="请输入手机号" /></Form.Item><Form.Item><Input size="large" placeholder="请输入验证码" /></Form.Item><Form.Item><Button type="primary" htmlType="submit" size="large" block>登录</Button></Form.Item></Form></Card></div>);
    };export default Login;
  • 表单校验实现

    • Form组件设置validateTrigger,为Form.Item组件设置namerules属性进行表单校验。
      import React from 'react';
      import { Form, Input, Button } from 'antd';const Login = () => {return (<Form validateTrigger={['onBlur']}><Form.Itemname="mobile"rules={[{ required: true, message: '请输入手机号' },{pattern: /^1[3-9]\d{9}$/,message: '手机号码格式不对'}]}><Input size="large" placeholder="请输入手机号" /></Form.Item><Form.Itemname="code"rules={[{ required: true, message: '请输入验证码' },]}><Input size="large" placeholder="请输入验证码" maxLength={6} /></Form.Item><Form.Item><Button type="primary" htmlType="submit" size="large" block>登录</Button></Form.Item></Form>);
      };export default Login;
  • 获取登录表单数据

    • Form组件设置onFinish属性,在点击登录按钮时触发获取表单数据的函数。
      import React from 'react';
      import { Form, Input, Button } from 'antd';const Login = () => {const onFinish = formValue => {console.log(formValue);};return (<Form onFinish={onFinish}><Form.Item><Input size="large" placeholder="请输入手机号" /></Form.Item><Form.Item><Input size="large" placeholder="请输入验证码" /></Form.Item><Form.Item><Button type="primary" htmlType="submit" size="large" block>登录</Button></Form.Item></Form>);
      };export default Login;
  • 封装 request 工具模块

    • 安装axios,在utils/request.js中创建axios实例,配置baseURL、请求拦截器和响应拦截器。
      # 安装axios
      npm i axios
      import axios from 'axios';const http = axios.create({baseURL: 'http://example.com/api',timeout: 5000
      });// 请求拦截器
      http.interceptors.request.use(config => {return config;
      }, error => {return Promise.reject(error);
      });// 响应拦截器
      http.interceptors.response.use(response => {return response.data;
      }, error => {return Promise.reject(error);
      });export { http };
  • 使用 Redux 管理 token

    • 安装react-redux@reduxjs/toolkit,在store中创建userStore切片,设置token初始状态和setUserInforeducers,封装fetchLogin异步方法。
      # 安装react-redux和@reduxjs/toolkit
      npm i react-redux @reduxjs/toolkit
      import { createSlice } from '@reduxjs/toolkit';
      import { http } from '@/utils';const userStore = createSlice({name: 'user',initialState: {token: ''},reducers: {setUserInfo(state, action) {state.token = action.payload;}}
      });const { setUserInfo } = userStore.actions;
      const userReducer = userStore.reducer;const fetchLogin = loginForm => {return async dispatch => {const res = await http.post('/authorizations', loginForm);dispatch(setUserInfo(res.data.token));};
      };export { fetchLogin };
      export default userReducer;
  • 实现登录逻辑

    • Login组件中调用fetchLogin方法,登录成功后跳转到首页并提示。
      import React from 'react';
      import { message } from 'antd';
      import { useDispatch } from 'react-redux';
      import { fetchLogin } from '@/store/modules/user';const Login = () => {const dispatch = useDispatch();const onFinish = async formValue => {await dispatch(fetchLogin(formValue));message.success('登录成功');};return (<div><form onSubmit={onFinish}>{/* 登录表单字段 */}</form></div>);
      };export default Login;
  • token 持久化

    • 封装setTokengetTokenclearToken方法,在userStoresetUserInfo时将token存入本地。
      // 在@/utils/token.js中封装存取方法
      const TOKENKEY = 'token_key';function setToken(token) {return localStorage.setItem(TOKENKEY, token);
      }function getToken() {return localStorage.getItem(TOKENKEY);
      }function clearToken() {return localStorage.removeItem(TOKENKEY);
      }export {setToken,getToken,clearToken
      };
      // 在userStore中使用token持久化方法
      import { createSlice } from '@reduxjs/toolkit';
      import { http } from '@/utils';
      import { getToken, setToken } from '@/utils/token';const userStore = createSlice({name: 'user',initialState: {token: getToken() || ''},reducers: {setUserInfo(state, action) {state.token = action.payload;setToken(state.token);}}
      });export default userStore;
  • 请求拦截器注入 token

    • request.js的请求拦截器中,判断是否有token,有则添加到请求头Authorization中。
      // 在utils/request.js中注入token
      import axios from 'axios';const http = axios.create({baseURL: 'http://example.com/api',timeout: 5000
      });http.interceptors.request.use(config => {const token = getToken();if (token) {config.headers.Authorization = `Bearer ${token}`;}return config;
      }, error => {return Promise.reject(error);
      });http.interceptors.response.use(response => {return response.data;
      }, error => {return Promise.reject(error);
      });export { http };
  • 路由鉴权实现

    • components/AuthRoute/index.jsx中创建路由鉴权高阶组件,判断本地是否有token,决定是否重定向到登录页面。
      import React from 'react';
      import { Navigate } from 'react-router-dom';
      import { getToken } from '@/utils';const AuthRoute = ({ children }) => {const isToken = getToken();if (isToken) {return <>{children}</>;} else {return <Navigate to="/login" replace />;}
      };export default AuthRoute;
      // 在src/router/index.js中使用AuthRoute组件
      import { createBrowserRouter } from 'react-router-dom';
      import Login from '@/pages/Login';
      import Layout from '@/pages/Layout';
      import AuthRoute from '@/components/AuthRoute';const router = createBrowserRouter([{path: '/',element: <AuthRoute><Layout /></AuthRoute>,},{path: '/login',element: <Login />,},
      ]);export default router;
  • Layout 模块

    • 基本结构和样式 reset

      • pages/Layout/index.js中使用antd/Layout组件创建页面结构,引入antdMenuPopconfirm等组件,设置样式并安装normalize.css进行样式 reset。
        import React from 'react';
        import { Layout, Menu, Popconfirm } from 'antd';
        import { HomeOutlined, DiffOutlined, EditOutlined, LogoutOutlined } from '@ant-design/icons';
        import './index.scss';
        import 'normalize.css';const { Header, Sider } = Layout;const items = [{label: '首页',key: '1',icon: <HomeOutlined />,},{label: '文章管理',key: '2',icon: <DiffOutlined />,},{label: '创建文章',key: '3',icon: <EditOutlined />,},
        ];const GeekLayout = () => {return (<Layout><Header className="header"><div className="logo" /><div className="user-info"><span className="user-name">用户名</span><span className="user-logout"><Popconfirm title="是否确认退出?" okText="退出" cancelText="取消"><LogoutOutlined /> 退出</Popconfirm></span></div></Header><Layout><Sider width={200} className="site-layout-background"><Menumode="inline"theme="dark"defaultSelectedKeys={['1']}items={items}style={{ height: '100%', borderRight: 0 }}></Menu></Sider><Layout className="layout-content" style={{ padding: 20 }}>内容</Layout></Layout></Layout>);
        };export default GeekLayout;
    • 二级路由配置

      • pages目录创建HomeArticlePublish页面文件夹,在router/index.js中配置嵌套子路由,在Layout中配置二级路由出口,使用Link修改左侧菜单内容实现路由切换。
        // 在pages目录创建Home.jsx
        import React from 'react';const Home = () => {return <div>首页内容</div>;
        };export default Home;
        // 在pages目录创建Article.jsx
        import React from 'react';const Article = () => {return <div>文章管理内容</div>;
        };export default Article;
        // 在pages目录创建Publish.jsx
        import React from 'react';const Publish = () => {return <div>发布文章内容</div>;
        };export default Publish;
        // 在src/router/index.js中配置二级路由
        import { createBrowserRouter } from 'react-router-dom';
        import Login from '@/pages/Login';
        import Layout from '@/pages/Layout';
        import Publish from '@/pages/Publish';
        import Article from '@/pages/Article';
        import Home from '@/pages/Home';
        import { AuthRoute } from '@/components/AuthRoute';const router = createBrowserRouter([{path: '/',element: (<AuthRoute><Layout /></AuthRoute>),children: [{index: true,element: <Home />,},{path: 'article',element: <Article />,},{path: 'publish',element: <Publish />,},],},{path: '/login',element: <Login />,},
        ]);export default router;
        // 在Layout组件中配置二级路由出口
        import React from 'react';
        import { Outlet } from 'react-router-dom';const GeekLayout = () => {return (<Layout className="layout-content" style={{ padding: 20 }}><Outlet /></Layout>);
        };export default GeekLayout;
    • 路由菜单点击交互实现

      • Menu组件设置onClick属性实现点击菜单跳转路由,通过useLocation获取当前路由路径实现菜单反向高亮。
        import React from 'react';
        import { Outlet, useNavigate } from 'react-router-dom';
        import { HomeOutlined, DiffOutlined, EditOutlined, LogoutOutlined } from '@ant-design/icons';const items = [{label: '首页',key: '/',icon: <HomeOutlined />,},{label: '文章管理',key: '/article',icon: <DiffOutlined />,},{label: '创建文章',key: '/publish',icon: <EditOutlined />,},
        ];const GeekLayout = () => {const navigate = useNavigate();const menuClick = route => {navigate(route.key);};return (<Layout><Header className="main-header"><div className="logo" /><div className="user-info"><span className="user-name">用户名</span><span className="user-logout"><Popconfirm title="是否确认退出?" okText="退出" cancelText="取消"><LogoutOutlined /> 退出</Popconfirm></span></div></Header><Layout><Sider width={200} className="site-layout-background"><Menumode="inline"theme="dark"selectedKeys={['1']}items={items}style={{ height: '100%', borderRight: 0 }}onClick={menuClick}></Menu></Sider><Layout className="layout-content" style={{ padding: 20 }}><Outlet /></Layout></Layout>);
        };export default GeekLayout;
        // 菜单反向高亮实现
        import React from 'react';
        import { Outlet, useLocation } from 'react-router-dom';
        import { HomeOutlined, DiffOutlined, EditOutlined, LogoutOutlined } from '@ant-design/icons';const items = [{label: '首页',key: '/',icon: <HomeOutlined />,},{label: '文章管理',key: '/article',icon: <DiffOutlined />,},{label: '创建文章',key: '/publish',icon: <EditOutlined />,},
        ];const GeekLayout = () => {const location = useLocation();const selectedKey = location.pathname;return (<Layout><Header className="main-header"><div className
    • 展示个人信息

      • store/userStore.js中编写获取用户信息的逻辑,在Layout组件中触发fetchUserInfo方法获取信息并渲染用户名。
        // store/userStore.js
        import { createSlice } from '@reduxjs/toolkit';
        import { http } from '@/utils';
        import { getToken, setToken } from '@/utils';const userStore = createSlice({name: 'user',initialState: {token: getToken() || '',userInfo: {}},reducers: {setUserToken(state, action) {state.token = action.payload;setToken(state.token);},setUserInfo(state, action) {state.userInfo = action.payload;},clearUserInfo(state) {state.token = '';state.userInfo = {};clearToken();}}
        });// 解构出actionCreater
        const { setUserToken, setUserInfo, clearUserInfo } = userStore.actions;
        // 获取reducer函数
        const userReducer = userStore.reducer;const fetchLogin = (loginForm) => {return async (dispatch) => {const res = await http.post('/authorizations', loginForm);dispatch(setUserToken(res.data.token));};
        };const fetchUserInfo = () => {return async (dispatch) => {const res = await http.get('/user/profile');dispatch(setUserInfo(res.data));};
        };export { fetchLogin, fetchUserInfo, clearUserInfo };
        export default userReducer;
    • 退出登录实现

      • Popconfirm添加确认回调事件,在store/userStore.js中新增clearUserInfo方法删除token和用户信息,在回调事件中调用该方法并返回登录页面。
        // pages/Layout/index.js
        import React, { useEffect } from 'react';
        import { Layout, Menu, Popconfirm } from 'antd';
        import {HomeOutlined,DiffOutlined,EditOutlined,LogoutOutlined,
        } from '@ant-design/icons';
        import { useDispatch, useSelector } from 'react-redux';
        import { fetchUserInfo } from '@/store/modules/user';const { Header, Sider } = Layout;const items = [// 菜单配置项
        ];const GeekLayout = () => {const dispatch = useDispatch();const name = useSelector(state => state.user.userInfo.name);useEffect(() => {dispatch(fetchUserInfo());}, [dispatch]);const loginOut = () => {dispatch(clearUserInfo());// 假设这里有合适的导航函数,替换为实际的导航逻辑// navigate('/login'); };return (<Layout><Header className="header"><div className="logo" /><div className="user-info"><span className="user-name">{name}</span><span className="user-logout"><Popconfirmtitle="是否确认退出?"okText="退出"cancelText="取消"onConfirm={loginOut}><LogoutOutlined /> 退出</Popconfirm></span></div></Header><Layout><Sider width={200} className="site-layout-background"><Menumode="inline"theme="dark"defaultSelectedKeys={['1']}items={items}style={{ height: '100%', borderRight: 0 }}></Menu></Sider><Layout className="layout-content" style={{ padding: 20 }}>{/* 页面内容 */}</Layout></Layout></Layout>);
        };export default GeekLayout;
    • 处理 Token 失效

      • http.interceptors.response中判断响应状态码为401时,清除token,跳转到登录页面并刷新页面。
        // 在http.js(假设是配置axios请求相关的文件)中处理Token失效
        import axios from 'axios';const http = axios.create({baseURL: 'http://example.com/api',timeout: 5000
        });http.interceptors.response.use((response) => {return response.data;
        }, (error) => {if (error.response && error.response.status === 401) {// 假设这里有合适的获取和清除token的函数,替换为实际的逻辑const token = getToken();if (token) {clearToken();}// 假设这里有合适的导航函数,替换为实际的导航逻辑// navigate('/login'); window.location.reload();}return Promise.reject(error);
        });export { http };

相关文章:

【React】入门Day04 —— 项目搭建及登录与表单校验、token 管理、路由鉴权实现

项目搭建 创建项目 # 使用npx创建项目 npx create-react-app my-react-app # 进入项目目录 cd my-react-app # 创建项目目录结构 mkdir -p src/{apis,assets,components,pages,store,utils} touch src/{App.js,index.css,index.js} 使用npx create-react-app创建项目&#xff0…...

CMake 属性之目录属性

【写在前面】 CMake 的目录属性是指在特定目录&#xff08;及其子目录&#xff09;范围内有效的设置。 这些属性不同于全局变量或目标&#xff08;Target&#xff09;属性&#xff0c;它们提供了一种机制&#xff0c;允许开发者为项目中的不同部分定义不同的构建行为。 通过目录…...

ChatGPT:引领人工智能新潮流!

一、ChatGPT 是什么&#xff1f; 1. ChatGPT 的强大功能和广泛应用。 ChatGPT 作为一款先进的 AI 语言模型&#xff0c;拥有众多强大功能。它可以进行文本生成、文本分类、情感分析、机器翻译等多种自然语言处理任务。同时&#xff0c;ChatGPT 还能进行对话式交互&#xff0c;…...

【银河麒麟高级服务器操作系统】安全配置基线相关分析全过程及解决方案

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 服务器环境以及配置 【机型】物理机或虚机 【…...

用Python实现图片转ASCII艺术:图像处理与字符艺术的完美结合

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 ASCII艺术是一种通过字符来表现图像的艺术形式,最早用于早期计算机显示器,它仅支持字符显示。如今,尽管图像分辨率和显示技术得到了极大的提升,ASCII艺术作为一种复古而别具一格的图像表现形式,仍然受到许多…...

大数据-162 Apache Kylin 全量增量Cube的构建 Segment 超详细记录 多图

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…...

Redis-缓存过期淘汰策略

缓存淘汰策略 生产上redis内存设置为多少 设置为最大内存的 3/4 redis 会占用物理机多少内存 默认大小是 0&#xff0c;64 位系统下表示不限制内存大小&#xff0c;32位系统表示 3G 如何设置修改redis内存大小 config get maxmemory 查看修改方式 配置文件 单位是字节 2.…...

如何设置LED电子显示屏的屏幕参数?

LED电子显示屏因其高亮度、低能耗和长寿命等优点&#xff0c;在广告、信息显示等领域得到了广泛应用。正确设置屏幕参数对于确保显示屏的最佳性能至关重要。以下是LED电子显示屏设置屏幕参数的步骤&#xff1a; 1. 确定屏幕参数 在开始设置之前&#xff0c;需要了解显示屏的基本…...

Spring Boot Starter Parent介绍

引言 spring-boot-starter-parent 是一个特殊的项目&#xff0c;为基于 Spring Boot 的应用程序提供默认配置和默认依赖。 在本 Spring Boot 教程中&#xff0c;我们将深入了解所有 Spring Boot 项目内部使用的 spring-boot-starter-parent 依赖项。我们将探讨此依赖项所提供…...

【含开题报告+文档+PPT+源码】基于SpringBoot乡村助农益农平台的设计与实现

开题报告 近年来&#xff0c;随着社会经济的快速发展和人民生活水平的提高&#xff0c;人们对优质农产品的需求越来越高。然而&#xff0c;传统的农产品销售管理模式存在一些问题。首先&#xff0c;农产品供应链信息不透明&#xff0c;导致生产者难以了解市场需求和价格变动趋…...

数据中心运维挑战:性能监控的困境与智能化解决方案的探寻

随着数字化进程的加速&#xff0c;数据中心已成为企业信息架构的核心支撑&#xff0c;其运维管理的复杂度和重要性也随之提升。运维团队需应对设备老化、资源分配失衡、性能波动等多重难题&#xff0c;以确保数据中心持续高效运行。 其中&#xff0c;性能监控作为运维管理的关键…...

基于SSM的民宿管理系统【附源码】

基于SSM的民宿管理系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1 系统概要设计 4.2 系统功能结构设计 4.3 数据库设计 4.3.1 数据库E-R图设计 4.3.2 数据库表结构设计 5 系统实现 5.1用户信息管理 5.2 房东信息管理…...

显卡 3090 vs v100

1.3090 Date: 2020 AmperePielines/ Cuda cores: 10496 2.V100 Date: 2018 VoltaPielines/ Cuda cores: 5129 3.结构 & Core比较: v100优点: v100功耗小v100较快的双精度(fp64)和混合精度(fp16fp32)pcie版的NVLink与2080ti完全一致 v100缺点: 不支持整数格式计算&…...

怎么在单片机裸机程序中移植EasyLogger?

1、介绍 EasyLogger 是一款超轻量级、高性能的C日志库&#xff0c;非常适合对资源敏感的软件项目。例如&#xff1a;IoT产品、可穿戴设备、智能家居等等。相比log4c、zlog这些知名的C日志库&#xff0c;EasyLogger的功能更加简单&#xff0c;提供给用户的接口更少&#xff0c;但…...

C/C++解析文件名和目录路径

文章目录 主要函数使用注意事项示例程序总结 #include <libgen.h> 是一个 C/C 语言的头文件&#xff0c;主要用于字符串处理&#xff0c;特别是在处理文件路径时。它提供了一些函数来帮助你解析文件名和目录路径。 主要函数 以下是 libgen.h 中一些常见的函数&#xff…...

Git 基本命令行操作

Git是一个开源的分布式版本控制系统&#xff0c;用于管理源代码和文档的版本。以下是Git的基本命令行操作&#xff1a; 一、配置 安装完成后&#xff0c;需要配置Git的用户名和邮箱&#xff0c;以便在提交记录时记录操作者的信息。 配置全局用户名&#xff1a;git config --g…...

【Rust练习】17.泛型

练习题来自&#xff1a;https://practice-zh.course.rs/generics-traits/generics.html 函数 1 // 填空 struct A; // 具体的类型 A. struct S(A); // 具体的类型 S. struct SGen<T>(T); // 泛型 SGen.fn reg_fn(_s: S) {}fn gen_spec_t(_s: SGen<A&…...

java脚手架系列4--测试用例、拦截器

异常处理、拦截器、数据库连接 1 测试用例 单元测试是一个老生常谈的问题&#xff0c;无论是后端对自己的代码质量把的第一道关也好&#xff0c;也是对测试减缓压力。这里就不过多讲述测试用例的重要性&#xff0c;但是有2个框架我们必须了解一下。 1.1 JUnit和mockito 我们…...

论文推荐 |【Agent】自动化Agent设计系统

论文标题&#xff1a; Automated Design of Agentic Systems 论文地址&#xff1a; https://arxiv.org/abs/2408.08435 GitHub地址&#xff1a; https://github.com/ShengranHu/ADAS 自动化代理设计在性能和通用性方面显著超越了手动方法。 • 引入了自动化代理系统设计&am…...

Linux操作系统提供了五种主要的IO(输入/输出)模型

Linux操作系统提供了五种主要的IO&#xff08;输入/输出&#xff09;模型&#xff0c;这些模型旨在优化应用程序对输入输出操作的管理和处理。以下是关于这五种IO模型的详细介绍。 一、阻塞IO&#xff08;Blocking IO&#xff09; 阻塞IO是最常见、最传统的IO模型。在这种模型…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...