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

React从基础入门到高级实战:React 实战项目 - 项目一:在线待办事项应用

React 实战项目:在线待办事项应用

欢迎来到本 React 开发教程专栏的第 26 篇!在之前的 25 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件、状态、路由和性能优化等核心知识。这一次,我们将通过一个完整的实战项目——在线待办事项应用,将这些知识融会贯通,帮助您从理论走向实践。

本项目的目标是为初学者提供一个简单但全面的 React 开发体验。通过这个项目,您将学习如何分析需求、选择技术栈、实现功能并最终将应用部署到线上。无论您是刚刚接触 React 的新手,还是希望通过实践巩固基础的开发者,这篇文章都将为您提供清晰的指引和丰富的代码示例。


引言

React 是一个强大的前端框架,其声明式编程和组件化特性让开发者能够高效地构建用户界面。然而,仅仅理解理论是不够的——真正的学习发生在实践中。在本项目中,我们将构建一个在线待办事项应用,这是一个经典的入门案例,既简单又实用,能够帮助您掌握 React 的核心技能。

这个应用的目标非常明确:允许用户创建、编辑和删除待办事项,支持按状态过滤,并将数据保存在本地,确保刷新页面后不会丢失。我们将从需求分析开始,逐步完成技术选型、代码实现和部署上线,并在最后提供一个练习,帮助您进一步巩固所学内容。

通过这个项目,您将体验到:

  • 组件化思维:如何将复杂的界面拆分为可重用的模块。
  • 状态管理:如何在应用中高效地共享和更新数据。
  • 路由设计:如何实现多页面导航。
  • 数据持久化:如何使用本地存储保存用户数据。

准备好了吗?让我们开始吧!


需求分析

在动手写代码之前,我们需要明确这个待办事项应用的具体功能需求。一个清晰的需求清单不仅能指导开发过程,还能帮助我们理解每个功能的意义。以下是我们项目的核心需求:

  1. 创建待办事项
    用户可以输入任务描述并添加到待办列表中。
  2. 编辑待办事项
    用户可以修改已有任务的内容。
  3. 删除待办事项
    用户可以移除不再需要的任务。
  4. 过滤待办事项
    用户可以根据任务状态(全部、已完成、未完成)筛选列表。
  5. 数据持久化
    数据将保存在浏览器本地存储中,刷新页面后依然可用。

为什么选择这些功能?

这些功能覆盖了待办事项应用的核心场景,同时也为学习 React 提供了丰富的实践机会:

  • 创建和编辑涉及表单处理和事件监听。
  • 删除和过滤需要掌握状态更新和数组操作。
  • 本地存储引入了数据持久化的概念。

此外,这些功能简单直观,非常适合初学者上手,同时也为后续扩展(如添加分类、优先级等)留下了空间。


技术栈选择

在开始实现之前,我们需要选择合适的技术栈。以下是本项目使用的工具和技术,以及选择它们的理由:

  • React
    核心框架,用于构建用户界面。React 的组件化和声明式编程让开发过程更加直观。
  • Vite
    构建工具,提供快速的开发服务器和高效的打包能力。相比传统的 Create React App,Vite 的启动速度更快,热更新体验更优。
  • React Router
    用于实现页面导航。虽然待办事项应用可以是单页应用,但我们将通过多页面设计展示路由的用法。
  • Context API
    React 内置的状态管理工具,用于在组件间共享待办事项数据。相比 Redux,它更轻量,适合小型项目。

技术栈的优势

  • React:生态丰富,学习曲线平滑,是现代前端开发的标配。
  • Vite:2025 年的前端开发趋势偏向轻量化和高性能,Vite 代表了这一方向。
  • React Router:支持动态路由和参数传递,是多页面应用的理想选择。
  • Context API:无需引入外部依赖,简单易用,适合初学者理解状态管理。

这些工具的组合不仅易于上手,还能帮助您掌握现代 React 开发的精髓。


项目实现

现在,我们进入最核心的部分——代码实现。我们将从项目搭建开始,逐步完成组件拆分、路由设计、状态管理和本地存储的开发。

1. 项目搭建

首先,使用 Vite 创建一个新的 React 项目:

npm create vite@latest todo-app -- --template react
cd todo-app
npm install
npm run dev

安装必要的依赖:

npm install react-router-dom

这将启动一个基础的 React 项目,接下来我们将逐步实现功能。

2. 组件拆分

组件化是 React 的核心思想。通过将应用拆分为多个小组件,我们可以提高代码的可读性和复用性。

组件结构
  • App:根组件,负责路由配置和整体布局。
  • TodoList:显示待办事项列表,包含过滤功能。
  • TodoItem:展示单个待办事项,支持编辑和删除。
  • TodoForm:用于添加或编辑待办事项的表单。
  • FilterButtons:提供状态过滤选项。
文件结构
src/
├── components/
│   ├── TodoList.jsx
│   ├── TodoItem.jsx
│   ├── TodoForm.jsx
│   └── FilterButtons.jsx
├── context/
│   └── TodoContext.jsx
├── App.jsx
└── main.jsx

3. 路由设计

我们将应用设计为多页面结构,使用 React Router 实现导航。

路由配置
  • /:首页,显示待办事项列表。
  • /add:添加待办事项页面。
  • /edit/:id:编辑指定待办事项页面。

App.jsx 中配置路由:

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import TodoList from './components/TodoList';
import TodoForm from './components/TodoForm';
import { TodoProvider } from './context/TodoContext';function App() {return (<TodoProvider><Router><div className="min-h-screen bg-gray-100 p-4"><Routes><Route path="/" element={<TodoList />} /><Route path="/add" element={<TodoForm />} /><Route path="/edit/:id" element={<TodoForm />} /></Routes></div></Router></TodoProvider>);
}export default App;
导航链接

TodoList 中添加导航到添加页面的按钮:

import { Link } from 'react-router-dom';function TodoList() {return (<div><h1 className="text-2xl font-bold mb-4">待办事项</h1><Link to="/add" className="bg-blue-500 text-white px-4 py-2 rounded">添加任务</Link>{/* 列表内容 */}</div>);
}export default TodoList;

4. 状态管理

我们使用 Context API 管理全局状态,包括待办事项列表和过滤条件。

创建 Context

src/context/TodoContext.jsx 中:

import { createContext, useState, useEffect } from 'react';export const TodoContext = createContext();export function TodoProvider({ children }) {const [todos, setTodos] = useState([]);const [filter, setFilter] = useState('all');// 加载本地存储数据useEffect(() => {const storedTodos = JSON.parse(localStorage.getItem('todos')) || [];setTodos(storedTodos);}, []);// 保存数据到本地存储useEffect(() => {localStorage.setItem('todos', JSON.stringify(todos));}, [todos]);return (<TodoContext.Provider value={{ todos, setTodos, filter, setFilter }}>{children}</TodoContext.Provider>);
}
使用 Context

TodoList 中访问和过滤数据:

import { useContext } from 'react';
import { TodoContext } from '../context/TodoContext';
import TodoItem from './TodoItem';
import FilterButtons from './FilterButtons';function TodoList() {const { todos, filter } = useContext(TodoContext);const filteredTodos = todos.filter((todo) => {if (filter === 'completed') return todo.completed;if (filter === 'incomplete') return !todo.completed;return true;});return (<div><h1 className="text-2xl font-bold mb-4">待办事项</h1><Link to="/add" className="bg-blue-500 text-white px-4 py-2 rounded mb-4 inline-block">添加任务</Link><FilterButtons /><ul className="space-y-2">{filteredTodos.map((todo) => (<TodoItem key={todo.id} todo={todo} />))}</ul></div>);
}export default TodoList;

5. 组件实现

TodoItem

TodoItem.jsx 中实现单个待办事项的展示和操作:

import { useContext } from 'react';
import { Link } from 'react-router-dom';
import { TodoContext } from '../context/TodoContext';function TodoItem({ todo }) {const { todos, setTodos } = useContext(TodoContext);const toggleComplete = () => {setTodos(todos.map((t) =>t.id === todo.id ? { ...t, completed: !t.completed } : t));};const deleteTodo = () => {setTodos(todos.filter((t) => t.id !== todo.id));};return (<li className="flex items-center justify-between p-2 bg-white rounded shadow"><div className="flex items-center"><inputtype="checkbox"checked={todo.completed}onChange={toggleComplete}className="mr-2"/><span className={todo.completed ? 'line-through text-gray-500' : ''}>{todo.text}</span></div><div><Linkto={`/edit/${todo.id}`}className="text-blue-500 mr-2">编辑</Link><button onClick={deleteTodo} className="text-red-500">删除</button></div></li>);
}export default TodoItem;
TodoForm

TodoForm.jsx 中实现添加和编辑表单:

import { useState, useContext, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { TodoContext } from '../context/TodoContext';function TodoForm() {const { todos, setTodos } = useContext(TodoContext);const { id } = useParams();const navigate = useNavigate();const [text, setText] = useState('');useEffect(() => {if (id) {const todo = todos.find((t) => t.id === id);if (todo) setText(todo.text);}}, [id, todos]);const handleSubmit = (e) => {e.preventDefault();if (!text.trim()) return;if (id) {// 编辑setTodos(todos.map((t) => (t.id === id ? { ...t, text } : t)));} else {// 添加const newTodo = {id: Date.now().toString(),text,completed: false,};setTodos([...todos, newTodo]);}navigate('/');};return (<div><h1 className="text-2xl font-bold mb-4">{id ? '编辑任务' : '添加任务'}</h1><form onSubmit={handleSubmit}><inputtype="text"value={text}onChange={(e) => setText(e.target.value)}className="w-full p-2 border rounded mb-4"placeholder="请输入任务描述"/><buttontype="submit"className="bg-blue-500 text-white px-4 py-2 rounded">保存</button></form></div>);
}export default TodoForm;
FilterButtons

FilterButtons.jsx 中实现过滤按钮:

import { useContext } from 'react';
import { TodoContext } from '../context/TodoContext';function FilterButtons() {const { filter, setFilter } = useContext(TodoContext);return (<div className="mb-4"><buttononClick={() => setFilter('all')}className={`mr-2 px-4 py-2 rounded ${filter === 'all' ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}>全部</button><buttononClick={() => setFilter('completed')}className={`mr-2 px-4 py-2 rounded ${filter === 'completed' ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}>已完成</button><buttononClick={() => setFilter('incomplete')}className={`px-4 py-2 rounded ${filter === 'incomplete' ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}>未完成</button></div>);
}export default FilterButtons;

6. 本地存储

本地存储已在 TodoContext 中实现,通过 localStorage 保存和加载数据,确保刷新页面后数据不会丢失。


部署

开发完成后,我们将应用部署到 Netlify,让它在线上运行。

1. 构建项目

运行以下命令生成静态文件:

npm run build

这会生成 dist 文件夹,包含应用的静态资源。

2. 部署到 Netlify

  1. 注册 Netlify:访问 Netlify 官网 并创建账号。
  2. 新建站点:在控制台选择“New site from Git”。
  3. 连接仓库:将项目推送至 GitHub 并连接。
  4. 配置构建
    • 构建命令:npm run build
    • 发布目录:dist
  5. 部署:点击“Deploy site”,等待部署完成。

部署成功后,您将获得一个唯一的 URL,可以通过它访问您的待办事项应用。


练习:添加分类功能

为了帮助您巩固所学,我们设计了一个练习:为待办事项添加分类功能。

需求

  • 用户可以为任务指定分类(如“工作”、“个人”、“学习”)。
  • 用户可以按分类过滤任务。

实现步骤

  1. 扩展数据结构
    todos 中为每个任务添加 category 字段。
  2. 更新 TodoForm
    添加分类选择下拉菜单。
  3. 更新过滤逻辑
    TodoListFilterButtons 中支持分类过滤。

示例代码

修改 TodoContext
export function TodoProvider({ children }) {const [todos, setTodos] = useState([]);const [filter, setFilter] = useState('all');useEffect(() => {const storedTodos = JSON.parse(localStorage.getItem('todos')) || [];setTodos(storedTodos);}, []);useEffect(() => {localStorage.setItem('todos', JSON.stringify(todos));}, [todos]);return (<TodoContext.Provider value={{ todos, setTodos, filter, setFilter }}>{children}</TodoContext.Provider>);
}
修改 TodoForm
function TodoForm() {const { todos, setTodos } = useContext(TodoContext);const { id } = useParams();const navigate = useNavigate();const [text, setText] = useState('');const [category, setCategory] = useState('工作');useEffect(() => {if (id) {const todo = todos.find((t) => t.id === id);if (todo) {setText(todo.text);setCategory(todo.category);}}}, [id, todos]);const handleSubmit = (e) => {e.preventDefault();if (!text.trim()) return;if (id) {setTodos(todos.map((t) =>t.id === id ? { ...t, text, category } : t));} else {const newTodo = {id: Date.now().toString(),text,category,completed: false,};setTodos([...todos, newTodo]);}navigate('/');};return (<div><h1 className="text-2xl font-bold mb-4">{id ? '编辑任务' : '添加任务'}</h1><form onSubmit={handleSubmit}><inputtype="text"value={text}onChange={(e) => setText(e.target.value)}className="w-full p-2 border rounded mb-4"placeholder="请输入任务描述"/><selectvalue={category}onChange={(e) => setCategory(e.target.value)}className="w-full p-2 border rounded mb-4"><option value="工作">工作</option><option value="个人">个人</option><option value="学习">学习</option></select><buttontype="submit"className="bg-blue-500 text-white px-4 py-2 rounded">保存</button></form></div>);
}
修改 TodoList 和 FilterButtons
function TodoList() {const { todos, filter } = useContext(TodoContext);const filteredTodos = todos.filter((todo) => {if (filter === 'completed') return todo.completed;if (filter === 'incomplete') return !todo.completed;if (['工作', '个人', '学习'].includes(filter)) return todo.category === filter;return true;});return (<div><h1 className="text-2xl font-bold mb-4">待办事项</h1><Link to="/add" className="bg-blue-500 text-white px-4 py-2 rounded mb-4 inline-block">添加任务</Link><FilterButtons /><ul className="space-y-2">{filteredTodos.map((todo) => (<TodoItem key={todo.id} todo={todo} />))}</ul></div>);
}function FilterButtons() {const { filter, setFilter } = useContext(TodoContext);return (<div className="mb-4 flex flex-wrap gap-2"><buttononClick={() => setFilter('all')}className={`px-4 py-2 rounded ${filter === 'all' ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}>全部</button><buttononClick={() => setFilter('completed')}className={`px-4 py-2 rounded ${filter === 'completed' ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}>已完成</button><buttononClick={() => setFilter('incomplete')}className={`px-4 py-2 rounded ${filter === 'incomplete' ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}>未完成</button><buttononClick={() => setFilter('工作')}className={`px-4 py-2 rounded ${filter === '工作' ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}>工作</button><buttononClick={() => setFilter('个人')}className={`px-4 py-2 rounded ${filter === '个人' ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}>个人</button><buttononClick={() => setFilter('学习')}className={`px-4 py-2 rounded ${filter === '学习' ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}>学习</button></div>);
}

练习目标

通过这个练习,您将学会如何扩展现有功能,提升对状态管理和组件通信的理解。


注意事项

  • 初学者友好:本文避免了复杂的概念,所有代码都尽量保持简单直观。
  • 学习建议:建议您边阅读边动手实现,遇到问题时查阅 React 官方文档和Vite 文档。
  • 扩展思路:完成项目后,可以尝试添加更多功能,如任务优先级、截止日期或提醒功能。

结语

通过这个在线待办事项应用项目,您从需求分析到部署上线,完整地走过了一个 React 项目的开发流程。您学习了组件拆分、路由设计、状态管理和数据持久化等核心技能,这些知识将成为您未来开发更复杂应用的基础。

相关文章:

React从基础入门到高级实战:React 实战项目 - 项目一:在线待办事项应用

React 实战项目&#xff1a;在线待办事项应用 欢迎来到本 React 开发教程专栏的第 26 篇&#xff01;在之前的 25 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件、状态、路由和性能优化等核心知识。这一次&#xff0c;我们将通过一个…...

云部署实战:基于AWS EC2/Aliyun ECS与GitHub Actions的CI/CD全流程指南

在当今快速迭代的软件开发环境中&#xff0c;云部署与持续集成/持续交付(CI/CD)已成为现代开发团队的标配。本文将详细介绍如何利用AWS EC2或阿里云ECS结合GitHub Actions构建高效的CI/CD流水线&#xff0c;从零开始实现自动化部署的全过程。 最近挖到一个宝藏级人工智能学习网…...

golang 如何定义一种能够与自身类型值进行比较的Interface

定义一种具有比较能力的类型是一种常见需求&#xff0c;比如对一组相同类型的值进行排序&#xff0c;就需要进行两两比较&#xff0c;那么在Go语言中有没有办法定义一种具有比较能力的Interface&#xff0c;实现该接口的类型都具备比较能力呢&#xff0c;最常见最容易的办法是定…...

Web前端之原生表格动态复杂合并行、Vue

MENU 效果公共数据纯原生StyleJavaScript vue原生table 效果 原生的JavaScript原生table null 公共数据 const list [{id: "a1",title: "第一列",list: [{id: "a11",parentId: "a1",title: "第二列",list: [{ id: "…...

『uniapp』把接口的内容下载为txt本地保存 / 读取本地保存的txt文件内容(详细图文注释)

目录 预览效果思路分析downloadTxt 方法readTxt 方法 完整代码总结 欢迎关注 『uniapp』 专栏&#xff0c;持续更新中 欢迎关注 『uniapp』 专栏&#xff0c;持续更新中 预览效果 思路分析 downloadTxt 方法 该方法主要完成两个任务&#xff1a; 下载 txt 文件&#xff1a;通…...

C/C++ 面试复习笔记(2)

C语言如何实现快速排序算法&#xff1f; 答案&#xff1a;快排是一种分治算法&#xff0c;选择一个基准元素&#xff0c;将数据划分成两部分&#xff0c;然后递归排序 补充&#xff1a; void quick_sort(int arr[], int start, int end) {//判断是否需要排序if (start > …...

宝马集团推进数字化转型:强化生产物流与财务流程,全面引入SAP现代架构

2025年6月&#xff0c;宝马集团宣布在生产物流与财务流程领域取得重大数字化成果。这些进展标志着集团全球范围内采用基于云的新型SAP架构进入关键阶段&#xff0c;旨在提升运营效率、透明度和AI能力&#xff0c;为未来工业发展奠定技术基础。 一、生产物流全球数字化部署 宝…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 时间事件处理部分)

揭秘高效存储模型与数据结构底层实现 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 时间事件&#xff1a;serverCron函数更新服务器时间缓存更新LRU时钟-lruclock更新服务器每秒执行命令次…...

【DAY40】训练和测试的规范写法

内容来自浙大疏锦行python打卡训练营 浙大疏锦行 知识点&#xff1a; 彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中展平操作&#xff1a;除第一个维度batchsize外全部展平dropout操作&#xff1a;训练阶段随机丢弃神经元&#xff0c;测试阶段eval模式关闭drop…...

C语言 标准I/O函数全面指南

C标准I/O函数全面指南 本指南详细介绍了C语言中用于文件操作的标准输入/输出函数&#xff0c;包括单字符I/O、字符串I/O、格式化I/O、块I/O以及文件光标操作。每个部分包含函数定义、使用说明和实用示例&#xff0c;适合学习、复习以及博客发布。内容采用清晰的Markdown格式&a…...

el-select 实现分页加载,切换也数滚回到顶部,自定义高度

el-select 实现分页加载&#xff0c;切换也数滚回到顶部&#xff0c;自定义高度 1.html <el-form-item label"俱乐部&#xff1a;" prop"club_id" label-width"120px"><el-select :disabled"Boolean(match_id)" style"w…...

Langchaine4j 流式输出 (6)

Langchaine4j 流式输出 大模型的流式输出是指大模型在生成文本或其他类型的数据时&#xff0c;不是等到整个生成过程完成后再一次性 返回所有内容&#xff0c;而是生成一部分就立即发送一部分给用户或下游系统&#xff0c;以逐步、逐块的方式返回结果。 这样&#xff0c;用户…...

Jenkins:自动化流水线的基石,开启 DevOps 新时代

从持续集成到持续交付的全流程自动化工具 一、什么是 Jenkins&#xff1f; Jenkins 是一款开源的 自动化服务器&#xff0c;专注于持续集成&#xff08;CI&#xff09;和持续交付&#xff08;CD&#xff09;。它通过插件化的架构支持几乎所有的开发、运维和测试工具&#xff…...

学习经验分享【40】目标检测热力图制作

目标检测热力图在学术论文&#xff08;尤其是计算机视觉、深度学习领域&#xff09;中是重要的可视化分析工具和论证辅助手段&#xff0c;可以给论文加分不少。主要作用一是增强论文的可解释性与说服力&#xff1a;论文中常需解释模型 “如何” 或 “为何” 检测到目标&#xf…...

C#里与嵌入式系统W5500网络通讯(3)

有与W5500通讯时,需要使用下面的寄存器: PHYCFGR (W5500 PHY Configuration Register) [R/W] [0x002E] [0b10111XXX] PHYCFGR configures PHY operation mode and resets PHY. In addition, PHYCFGR indicates the status of PHY such as duplex, Speed, Link. 这张表格详细…...

用OpenNI2获取奥比中光Astra Pro输出的深度图(win,linux arm64 x64平台)

搞了一个奥比中光Astra Pro&#xff0c;想在windows平台&#xff0c;和linux rk3588 &#xff08;香橙派&#xff0c;ubuntu2404,debian)上获取深度信息&#xff0c;之前的驱动下载已经不好用了,参考如下 Astra 3D相机选型建议 - 知乎https://zhuanlan.zhihu.com/p/594485674 …...

Unity VR/MR开发-VR设备与适用场景分析

视频讲解链接&#xff1a;【XR马斯维】VR/MR设备与适用场景分析&#xff1f;【UnityVR/MR开发教程--入门】_游戏热门视频...

Linux: network: switch:arp cache更新规则 [chatGPT]

文章目录 介绍概念普通包带有不同的mac,是否更新arp cache?普通包带有相同的mac,是否刷新 aging timeswitch是否会主动学习介绍 关于arp cache在switch侧的行为。有很多问题需要理解。 概念 HP L3 - IP Services Configuration Guide 文档里有写:dynamic arp entry的解说…...

Java网络编程API 1

Java中的网络编程API一共有两套&#xff1a;一套是UDP协议使用的API&#xff1b;另一套是TCP协议使用的API。这篇文章我们先来介绍UDP版本的API&#xff0c;并尝试来写一个回显服务器&#xff08;接收到的请求是什么&#xff0c;返回的响应就是什么&#xff09;。 UDP数据报套…...

Android协程学习

目录 Android上的Kotlin协程介绍基本概念与简单使用示例协程的高级用法 结构化并发线程调度器(Dispatchers)自定义调度器并发:同步 vs 异步 异步并发(async 并行执行)同步顺序执行协程取消与超时 取消机制超时控制异步数据流 Flow协程间通信 使用 Channel使用 StateFlow /…...

Angular报错:cann‘t bind to ngClass since it is‘t a known property of div

遇到的错误&#xff1a; Cant bind to ngClass since it isnt a known property of div这个错误是 Angular 中 最常见的模板编译错误之一&#xff0c;通常出现在你试图使用 ngClass 指令&#xff0c;但 Angular 没有识别它的情况下。 ✅ 错误的根本原因 Angular 不知道 ngCla…...

uniapp+vue3实现CK通信协议(基于jjc-tcpTools)

1. TCP 服务封装 (tcpService.js) export class TcpService {constructor() {this.connections uni.requireNativePlugin(jjc-tcpTools)this.clients new Map() // 存储客户端连接this.servers new Map() // 存储服务端实例}// 创建 TCP 服务端 (字符串模式)createStringSe…...

Python爬虫实战:研究urlparse库相关技术

1 引言 1.1 研究背景与意义 网络爬虫作为互联网数据采集的核心技术,在信息检索、舆情分析、数据挖掘等领域具有广泛应用。随着 Web 技术的发展,现代网站 URL 结构日益复杂,包含路径参数、查询参数、锚点等多种组件,且存在相对路径、URL 编码等问题,给爬虫开发带来了挑战…...

解锁FastAPI与MongoDB聚合管道的性能奥秘

title: 解锁FastAPI与MongoDB聚合管道的性能奥秘 date: 2025/05/20 20:24:47 updated: 2025/05/20 20:24:47 author: cmdragon excerpt: MongoDB聚合管道是一种分阶段处理数据的流水线&#xff0c;通过$match、$group等阶段对文档进行特定操作&#xff0c;具有内存优化和原生操…...

软件工程方法论:在确定性与不确定性的永恒之舞中寻找平衡

更多精彩请访问&#xff1a;通义灵码2.5——基于编程智能体开发Wiki多功能搜索引擎-CSDN博客 当我们谈论“软件工程”时&#xff0c;“工程”二字总暗示着某种如桥梁建造般的精确与可控。然而&#xff0c;软件的本质却根植于人类思维的复杂性与需求的流变之中。软件工程方法论的…...

Unity中的MonoSingleton<T>与Singleton<T>

1.MonoSingleton 代码部分 using UnityEngine;/// <summary> /// MonoBehaviour单例基类 /// 需要挂载到GameObject上使用 /// </summary> public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T> {private static T _instance;…...

怎么通过 jvmti 去 hook java 层函数

使用 JVMTI 手动实现 Android Java 函数 Hook 要通过 JVMTI 手动实现 Android Java 函数 Hook&#xff0c;需要编写 Native 层代码并注入到目标进程中。以下是详细步骤和示例&#xff1a; 一、核心实现原理 JVMTI 提供两种主要 Hook 方式&#xff1a; Method Entry/Exit 事…...

兰亭妙微 | 医疗软件的界面设计能有多专业?

从医疗影像系统到手术机器人控制界面&#xff0c;从便携式病原体检测设备到多平台协同操作系统&#xff0c;兰亭妙微为众多医疗设备研发企业&#xff0c;打造了兼具专业性与可用性的交互界面方案。 我们不仅做设计&#xff0c;更深入理解医疗场景的实际需求&#xff1a; 对精…...

前端原生构建交互式进度步骤组件(Progress Steps)

在现代网页设计中&#xff0c;进度步骤&#xff08;Progress Steps&#xff09; 是一种常见的 UI 模式&#xff0c;常用于引导用户完成注册流程、多步表单、教程或任何需要分步骤操作的场景。本文将带你从零开始构建一个美观且功能完整的 “进度步骤”组件&#xff0c;并详细讲…...

如何给windos11 扩大C盘容量

动不动C盘就慢了&#xff0c;苹果逼着用户换手机&#xff0c;三天两头更新系统&#xff0c;微软也是毫不手软。c盘 从10个G就够用&#xff0c;到100G 也不够&#xff0c;看来通货膨胀是部分行业的。 在 Windows 11 中扩大 C 盘容量&#xff0c;主要取决于磁盘分区布局和可用空…...