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

六十天前端强化训练之第十七天React Hooks 入门:useState 深度解析

=====欢迎来到编程星辰海的博客讲解======

看完可以给一个免费的三连吗,谢谢大佬!

目录

一、知识讲解

1. Hooks 是什么?

2. useState 的作用

3. 基本语法解析

4. 工作原理

5. 参数详解

a) 初始值设置方式

b) 更新函数特性

6. 注意事项

7. 类组件对比

8. 常见问题解答

二、核心代码示例

三、实现效果

四、学习要点总结

五、扩展阅读推荐

官方文档

优质文章

推荐学习路径

进阶资源

六、实践步骤

一、表单输入控制

二、动态列表组件

三、购物车组件(复杂状态)

四、自定义Hook:useCart

推荐练习项目:


一、知识讲解

1. Hooks 是什么?

React Hooks 是 React 16.8 引入的革命性特性,它允许开发者在函数组件中使用状态(state)和其他 React 特性。Hooks 的诞生解决了以下问题:

  • 类组件中生命周期函数带来的逻辑分散
  • 高阶组件带来的嵌套地狱(Wrapper Hell)
  • 函数组件无法使用状态的局限
  • 状态逻辑难以复用的问题

2. useState 的作用

useState 是最基础且重要的 Hook,它让函数组件具备管理局部状态的能力。其核心功能包括:

  • 声明组件内部状态
  • 提供状态更新方法
  • 触发组件重新渲染
  • 保持状态在多次渲染间的持久性

3. 基本语法解析

JAVASCRIPT

const [state, setState] = useState(initialState);

  • initialState:状态的初始值,可以是任何数据类型
  • state:当前状态值
  • setState:用于更新状态的函数

4. 工作原理

  • 初始化阶段:组件首次渲染时,useState 会读取初始值并保存
  • 更新阶段:调用 setState 后:
    1. 将新值加入更新队列
    2. 触发组件重新渲染
    3. 在下次渲染时返回更新后的状态
  • 渲染机制:每次渲染都有独立的状态快照(闭包特性)

5. 参数详解

a) 初始值设置方式

JAVASCRIPT

// 直接值初始化
const [count, setCount] = useState(0);// 函数式初始化(惰性初始化)
const [count, setCount] = useState(() => {const initialValue = calculateExpensiveValue();return initialValue;
});
b) 更新函数特性
  • 支持直接赋值更新:

    JAVASCRIPT

    setCount(5);
    
  • 支持函数式更新(推荐用于依赖前值的场景):

    JAVASCRIPT

    setCount(prevCount => prevCount + 1);
    

6. 注意事项

  • 异步更新:状态更新是异步的,不能立即获取到新值
  • 合并更新:React 会自动合并多个 setState 调用
  • 性能优化:使用函数式更新避免闭包陷阱
  • 不可变原则:始终返回新值而不是修改原值

7. 类组件对比

特性类组件函数组件 + useState
状态初始化constructoruseState 参数
状态更新方式this.setState()setState 函数
状态访问this.state直接使用状态变量
生命周期依赖需要无需
代码组织分散在各个生命周期方法中逻辑集中

8. 常见问题解答

Q:useState 和类组件的 state 有何不同?
A:useState 不会自动合并对象类型的状态,需要手动合并

Q:为什么 setCount(count + 1) 在异步操作中不可靠?
A:由于闭包特性,异步回调中的 count 可能不是最新值,应该使用函数式更新

Q:可以在条件语句中使用 useState 吗?
A:不行,所有 Hooks 都必须保证每次渲染的调用顺序一致

Q:如何存储复杂对象?

JAVASCRIPT

const [user, setUser] = useState({name: 'John',age: 25,address: {city: 'New York',zip: '10001'}
});// 正确更新方式
setUser(prev => ({...prev,age: 26,address: {...prev.address,zip: '10002'}
}));

二、核心代码示例

JSX

import React, { useState } from 'react';function Counter() {// 声明状态变量 count 及其更新函数 setCount// 初始值设为 0const [count, setCount] = useState(0);// 定义增加计数器的方法const increment = () => {// 使用函数式更新确保基于最新状态值setCount(prevCount => prevCount + 1);};// 定义减少计数器的方法const decrement = () => {setCount(prevCount => prevCount - 1);};// 定义重置计数器的方法const reset = () => {setCount(0);};return (<div style={styles.container}><h2>当前计数: {count}</h2><div style={styles.buttonGroup}>{/* 绑定点击事件 */}<button style={styles.button} onClick={increment}>+</button><button style={styles.button} onClick={decrement}>-</button><button style={styles.button} onClick={reset}>重置</button></div>{/* 条件渲染提示信息 */}{count >= 10 && <p style={styles.tip}>计数已经超过10啦!</p>}</div>);
}// 样式对象
const styles = {container: {textAlign: 'center',padding: '2rem',backgroundColor: '#f0f0f0',borderRadius: '8px',maxWidth: '400px',margin: '2rem auto'},buttonGroup: {display: 'flex',justifyContent: 'center',gap: '1rem',marginTop: '1rem'},button: {padding: '0.5rem 1rem',fontSize: '1.2rem',cursor: 'pointer',backgroundColor: '#2196f3',color: 'white',border: 'none',borderRadius: '4px',transition: 'background-color 0.3s'},tip: {color: '#d32f2f',marginTop: '1rem',fontWeight: 'bold'}
};export default Counter;

三、实现效果

计数器组件包含:

  1. 显示当前数值的标题
  2. "+"、"-" 和 "重置" 三个操作按钮
  3. 当数值 >=10 时显示提示信息
  4. 按钮悬停时的颜色变化效果
  5. 整洁的卡片式布局

四、学习要点总结

  1. 基础概念

    • useState 是用于给函数组件添加状态管理的 Hook
    • 遵循 const [state, setState] = useState(initialValue) 语法
  2. 使用规则

    • 只在组件的顶层调用 Hooks
    • 不要在循环、条件或嵌套函数中调用 Hooks
    • 遵循不可变原则(immutability)
  3. 最佳实践

    • 对于复杂对象,使用扩展运算符进行合并更新
    • 异步操作时使用函数式更新确保获取最新状态
    • 拆分多个 useState 管理不同状态
  4. 性能优化

    • 对于昂贵的初始化,使用函数式初始化
    • 当更新依赖前值时,必须使用函数式更新
    • 使用 React.memo 防止不必要的重新渲染
  5. 常见错误

    • 直接修改状态对象

    JAVASCRIPT

    // 错误示例
    const [user, setUser] = useState({name: 'John'});
    user.name = 'Mike'; // 直接修改原对象
    setUser(user);      // 不会触发更新// 正确做法
    setUser({...user, name: 'Mike'});
    
  • 在渲染函数中执行副作用操作
  • 忽视异步更新的特性

五、扩展阅读推荐

官方文档

  1. Hooks 简介
  2. useState API 文档
  3. Hooks 常见问题

优质文章

  1. useState 完全指南
  2. Hooks 原理剖析
  3. 函数式更新深入解析
  4. Hooks 最佳实践
  5. Hooks 与类组件对比

推荐学习路径

  1. 掌握 useState → useEffect → useContext 基础三件套
  2. 学习自定义 Hook 实现逻辑复用
  3. 了解 useReducer 管理复杂状态
  4. 学习性能优化相关 Hooks(useMemo/useCallback)
  5. 探索第三方 Hooks 库(如 ahooks)

进阶资源

  1. React Hooks 完全指南(免费电子书)
  2. Hooks 实现原理视频解析
  3. Hooks 测试策略

六、实践步骤

可以以下步骤进行实践:

  1. 从简单计数器开始
  2. 实现表单输入控制
  3. 创建动态列表组件
  4. 开发带有复杂状态的购物车
  5. 尝试将业务逻辑抽象为自定义 Hooks

一、表单输入控制

JSX

import React, { useState } from 'react';function UserForm() {// 使用单个对象管理所有表单字段const [formData, setFormData] = useState({username: '',email: '',password: '',newsletter: false});// 统一处理输入变化const handleInputChange = (e) => {const { name, value, type, checked } = e.target;setFormData(prev => ({...prev,[name]: type === 'checkbox' ? checked : value}));};// 处理表单提交const handleSubmit = (e) => {e.preventDefault();console.log('表单提交数据:', formData);alert(JSON.stringify(formData, null, 2));};return (<form style={formStyles} onSubmit={handleSubmit}><div style={inputGroup}><label>用户名:</label><inputtype="text"name="username"value={formData.username}onChange={handleInputChange}/></div><div style={inputGroup}><label>邮箱:</label><inputtype="email"name="email"value={formData.email}onChange={handleInputChange}/></div><div style={inputGroup}><label>密码:</label><inputtype="password"name="password"value={formData.password}onChange={handleInputChange}/></div><div style={checkboxGroup}><label><inputtype="checkbox"name="newsletter"checked={formData.newsletter}onChange={handleInputChange}/>订阅新闻邮件</label></div><button type="submit" style={submitButton}>提交</button></form>);
}// 样式配置
const formStyles = {maxWidth: '400px',margin: '2rem auto',padding: '2rem',backgroundColor: '#f8f9fa',borderRadius: '8px'
};const inputGroup = {marginBottom: '1rem'
};const checkboxGroup = {margin: '1rem 0'
};const submitButton = {backgroundColor: '#28a745',color: 'white',padding: '0.5rem 1rem',border: 'none',borderRadius: '4px',cursor: 'pointer'
};export default UserForm;

学习要点:

  1. 使用对象统一管理表单状态
  2. 处理多种输入类型(文本/复选框)
  3. 动态属性名更新技巧([name]: value)
  4. 表单提交时访问最新状态

二、动态列表组件

JSX

import React, { useState } from 'react';function TodoList() {const [todos, setTodos] = useState([{ id: 1, text: '学习React Hooks', completed: false },{ id: 2, text: '练习useState', completed: true }]);const [newTodo, setNewTodo] = useState('');// 添加新待办事项const addTodo = () => {if (newTodo.trim()) {setTodos([...todos, {id: Date.now(),text: newTodo,completed: false}]);setNewTodo('');}};// 切换完成状态const toggleTodo = (id) => {setTodos(todos.map(todo =>todo.id === id ? { ...todo, completed: !todo.completed } : todo));};// 删除待办事项const deleteTodo = (id) => {setTodos(todos.filter(todo => todo.id !== id));};return (<div style={container}><h2>待办事项列表 ({todos.length})</h2><div style={inputGroup}><inputtype="text"value={newTodo}onChange={(e) => setNewTodo(e.target.value)}placeholder="输入新事项"style={inputStyle}/><button onClick={addTodo} style={addButton}>添加</button></div><ul style={listStyle}>{todos.map(todo => (<li key={todo.id} style={itemStyle(todo.completed)}><inputtype="checkbox"checked={todo.completed}onChange={() => toggleTodo(todo.id)}/><span style={{ flex: 1 }}>{todo.text}</span><button onClick={() => deleteTodo(todo.id)}style={deleteButton}>删除</button></li>))}</ul></div>);
}// 样式配置
const container = {maxWidth: '600px',margin: '2rem auto',padding: '1rem'
};const inputGroup = {display: 'flex',gap: '0.5rem',marginBottom: '1rem'
};const inputStyle = {flex: 1,padding: '0.5rem'
};const addButton = {backgroundColor: '#17a2b8',color: 'white',border: 'none',padding: '0.5rem 1rem',borderRadius: '4px',cursor: 'pointer'
};const listStyle = {listStyle: 'none',padding: 0
};const itemStyle = (completed) => ({display: 'flex',alignItems: 'center',padding: '0.5rem',margin: '0.5rem 0',backgroundColor: completed ? '#d4edda' : '#fff',border: '1px solid #ddd',borderRadius: '4px',opacity: completed ? 0.7 : 1
});const deleteButton = {backgroundColor: '#dc3545',color: 'white',border: 'none',padding: '0.25rem 0.5rem',borderRadius: '4px',cursor: 'pointer'
};export default TodoList;

学习要点:

  1. 使用数组管理动态列表
  2. 列表项的增删改操作
  3. 正确使用key属性
  4. 复杂状态对象的更新方法
  5. 条件样式渲染技巧

三、购物车组件(复杂状态)

JSX

import React, { useState } from 'react';const initialProducts = [{ id: 1, name: '商品A', price: 100, quantity: 1 },{ id: 2, name: '商品B', price: 200, quantity: 2 }
];function ShoppingCart() {const [cart, setCart] = useState(initialProducts);const [newProduct, setNewProduct] = useState('');// 计算总价const total = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);// 添加新商品const addProduct = () => {if (newProduct.trim()) {setCart([...cart, {id: Date.now(),name: newProduct,price: Math.floor(Math.random() * 500) + 100,quantity: 1}]);setNewProduct('');}};// 更新商品数量const updateQuantity = (id, delta) => {setCart(cart.map(item => {if (item.id === id) {const newQuantity = Math.max(1, item.quantity + delta);return { ...item, quantity: newQuantity };}return item;}));};// 移除商品const removeProduct = (id) => {setCart(cart.filter(item => item.id !== id));};return (<div style={container}><h2>购物车 (总价: ¥{total})</h2><div style={inputGroup}><inputtype="text"value={newProduct}onChange={(e) => setNewProduct(e.target.value)}placeholder="输入商品名称"style={inputStyle}/><button onClick={addProduct} style={addButton}>添加商品</button></div><ul style={listStyle}>{cart.map(item => (<li key={item.id} style={itemStyle}><div style={itemInfo}><span style={itemName}>{item.name}</span><span>单价: ¥{item.price}</span></div><div style={quantityControls}><button onClick={() => updateQuantity(item.id, -1)}style={controlButton}>-</button><span style={quantityDisplay}>{item.quantity}</span><button onClick={() => updateQuantity(item.id, 1)}style={controlButton}>+</button></div><div style={itemSubtotal}>小计: ¥{item.price * item.quantity}<buttononClick={() => removeProduct(item.id)}style={removeButton}>删除</button></div></li>))}</ul></div>);
}// 样式配置
const container = {maxWidth: '800px',margin: '2rem auto',padding: '1rem'
};const inputGroup = {display: 'flex',gap: '0.5rem',marginBottom: '1rem'
};const inputStyle = {flex: 1,padding: '0.5rem'
};const addButton = {backgroundColor: '#007bff',color: 'white',border: 'none',padding: '0.5rem 1rem',borderRadius: '4px',cursor: 'pointer'
};const listStyle = {listStyle: 'none',padding: 0
};const itemStyle = {display: 'flex',justifyContent: 'space-between',alignItems: 'center',padding: '1rem',margin: '0.5rem 0',backgroundColor: '#fff',border: '1px solid #ddd',borderRadius: '4px'
};const itemInfo = {flex: 2,display: 'flex',flexDirection: 'column',gap: '0.5rem'
};const itemName = {fontWeight: 'bold'
};const quantityControls = {display: 'flex',alignItems: 'center',gap: '0.5rem'
};const controlButton = {padding: '0.25rem 0.5rem',minWidth: '32px',backgroundColor: '#6c757d',color: 'white',border: 'none',borderRadius: '4px',cursor: 'pointer'
};const quantityDisplay = {minWidth: '30px',textAlign: 'center'
};const itemSubtotal = {flex: 1,display: 'flex',flexDirection: 'column',alignItems: 'flex-end',gap: '0.5rem'
};const removeButton = {backgroundColor: '#dc3545',color: 'white',border: 'none',padding: '0.25rem 0.5rem',borderRadius: '4px',cursor: 'pointer'
};export default ShoppingCart;

学习要点:

  1. 多层嵌套状态的管理
  2. 复杂状态更新模式
  3. 派生状态(总价)的计算
  4. 不可变数据更新模式
  5. 复杂组件的样式组织

四、自定义Hook:useCart

JSX

// useCart.js
import { useState } from 'react';function useCart(initialItems = []) {const [cart, setCart] = useState(initialItems);const total = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);const addItem = (newItem) => {setCart([...cart, {...newItem,id: Date.now(),quantity: 1}]);};const updateQuantity = (itemId, delta) => {setCart(currentCart =>currentCart.map(item =>item.id === itemId? { ...item, quantity: Math.max(1, item.quantity + delta) }: item));};const removeItem = (itemId) => {setCart(currentCart => currentCart.filter(item => item.id !== itemId));};return {cart,total,addItem,updateQuantity,removeItem};
}export default useCart;// 使用示例
function CartComponent() {const { cart, total, addItem, updateQuantity, removeItem } = useCart();// ...组件实现与前面购物车示例类似
}

学习要点:

  1. 自定义Hook的命名规范(必须用use开头)
  2. 状态逻辑的封装
  3. Hook之间的通信
  4. 返回可操作的方法集
  5. 实现业务逻辑复用

推荐练习项目:

  • 个人博客系统
  • 任务管理系统(类似Trello)
  • 电子商务平台
  • 实时数据监控仪表盘

学完后建议弄清以下问题:

  1. 状态更新的原理是什么?
  2. 如何避免不必要的重新渲染?
  3. 复杂状态如何组织更合理?
  4. 如何调试状态变化?
  5. 如何测试Hook相关逻辑?

相关文章:

六十天前端强化训练之第十七天React Hooks 入门:useState 深度解析

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、知识讲解 1. Hooks 是什么&#xff1f; 2. useState 的作用 3. 基本语法解析 4. 工作原理 5. 参数详解 a) 初始值设置方式 b) 更新函数特性 6. 注意事项 7. 类组…...

解决 HTTP 请求中的编码问题:从乱码到正确传输

文章目录 解决 HTTP 请求中的编码问题&#xff1a;从乱码到正确传输1. **问题背景**2. **乱码问题的原因**2.1 **客户端编码问题**2.2 **请求头缺失**2.3 **服务器编码问题** 3. **解决方案**3.1 **明确指定请求体编码**3.2 **确保请求头正确**3.3 **动态获取响应编码** 4. **调…...

跨国企业网络案例分析:SD-WAN智能组网

跨国企业面临的网络问题日益增加&#xff0c;如全球供应链协同、跨国研发协作及实时生产数据传输等场景&#xff0c;对网络质量提出更高要求。本文将深度解析某跨国工业集团如何通过SD-WAN实现网络架构智能化转型。 该集团以上海全球总部为核心&#xff0c;构建了覆盖亚欧美三大…...

视频孪生与三维视频融合:重构工业现场的“数字视网膜“

在浙江某精密制造企业的总控中心&#xff0c;30米长的曲面屏上实时跳动着工厂的每个生产细节&#xff1a;机械臂的运动轨迹与数字模型完全同步&#xff0c;质检工位的操作误差被自动标记&#xff0c;AGV小车的行进路径在三维空间中以光带形式可视化呈现。这种虚实交融的场景并非…...

STM32Cubemx-H7-7-OLED屏幕

如何把江科大的OLED标准库文件换成hal库的文件 前言 本文讲解如在hHAL库中使用OLED&#xff0c;其实江科大做的文件好已经很好了 只讲操作&#xff0c;不讲废话&#xff0c;默认大家都有32基本操作 创建工程 首先创建工程 把那两个引脚设置成开漏 获取标准库文件 打开江科大O…...

FPGA为何要尽量减少组合逻辑的使用

在FPGA设计中&#xff0c;组合逻辑的使用确实需要谨慎&#xff0c;尤其是要尽量减少它的复杂性。这并不是因为组合逻辑本身不好&#xff0c;而是因为它在实际应用中容易引发一系列问题&#xff0c;而这些问题往往与FPGA的设计哲学和硬件特性相冲突。让我从几个关键点来和你聊聊…...

缓存使用的具体场景有哪些?缓存的一致性问题如何解决?缓存使用常见问题有哪些?

缓存使用场景、一致性及常见问题解析 一、缓存的核心使用场景 1. 高频读、低频写场景 典型场景&#xff1a;商品详情页、新闻资讯、用户基本信息。特点&#xff1a;数据更新频率低&#xff0c;但访问量极高。策略&#xff1a; Cache-Aside&#xff08;旁路缓存&#xff09;&a…...

基于 RWA 模型与 AI - Agent 协同的企业级 aPAAS 架构设计

一、引言 在企业数字化转型不断深化的当下&#xff0c;现实世界资产&#xff08;RWA&#xff09;模型与人工智能智能体&#xff08;AI - Agent&#xff09;的协同融合&#xff0c;为企业级应用平台即服务&#xff08;aPAAS&#xff09;架构的创新发展带来了新契机。这种架构旨在…...

基于“动手学强化学习”的知识点(一):第 14 章 SAC 算法(gym版本 >= 0.26)

第 14 章 SAC 算法&#xff08;gym版本 &#xff1e; 0.26&#xff09; 摘要SAC 算法&#xff08;连续&#xff09;SAC 算法&#xff08;离散&#xff09; 摘要 本系列知识点讲解基于动手学强化学习中的内容进行详细的疑难点分析&#xff01;具体内容请阅读动手学强化学习&…...

【QT:信号和槽】

QT信号涉及的三要素&#xff1a;信号源、信号类型、信号的处理方式。 QT的信号槽机制&#xff1a; 给按钮的点击操作关联一个处理函数&#xff0c;用户点击按钮时触发&#xff0c;对应的处理函数就会执行 QT中使用connect函数将信号和槽关联起来&#xff0c;信号触发&#xf…...

Oracle中的INHERIT PRIVILEGES权限

Oracle中的INHERIT PRIVILEGES权限 存储过程和用户函数的AUTHID属性调用者权限vs定义者权限一个简单的示例INHERIT PRIVILEGES权限的含义INHERIT PRIVILEGES权限的安全隐患注意到Oracle 19c数据库中有如下权限信息: SQL> select grantor,grantee,table_name,privilege fro…...

Compose笔记(九)--Checkbox

这一节主要了解一下Compose中的Checkbox&#xff0c;它是Jetpack Compose UI框架中的一个组件&#xff0c;用于创建复选框功能。它允许用户从一个集合中选择一个或多个项目&#xff0c;可以将一个选项打开或关闭。与传统的Android View系统中的Checkbox相比&#xff0c;Compose…...

CSS中粘性定位

1.如何设置为粘性定位? 给元素设置posttion:sticky 即可实现粘性定位. 可以使用left, right ,top, bottom 四个属性调整位置,不过最常用的是top 值. 2.粘性定位的参考点在哪里? 离他最近的一个拥有"滚动机制"的祖先元素,即便这个祖先不是最近的真实可滚动祖先. 3.粘…...

日本IT|AWS工作内容及未来性、以及转职的所需资质和技能

AWSとは AWSはAmazon Web Services&#xff08;アマゾンウェブサービス&#xff09;の略称です。 名称から分かるとおり、ネットを通じた通販などを事業として行っているAmazon.com社がクラウドサービスとして運営しています。 本来であれば自分たちでインフラ環境を構築する…...

《Spring日志整合与注入技术:从入门到精通》

1.Spring与日志框架的整合 1.Spring与日志框架进行整合&#xff0c;日志框架就可以在控制台中&#xff0c;输出Spring框架运行过程中的一些重要的信息。 好处&#xff1a;方便了解Spring框架的运行过程&#xff0c;利于程序的调试。 Spring如何整合日志框架 Spring5.x整合log4j…...

如何判断一个项目用的是哪个管理器

如何判断一个项目用的是哪个管理器 npm: 如果项目中存在 package-lock.json 文件&#xff0c;这通常意味着项目使用 npm 作为包管理器。package-lock.json 文件会锁定项目的依赖版本&#xff0c;确保在不同环境中安装相同的依赖。 pnpm: 如果项目中存在 pnpm-lock.yaml 文件&a…...

软件工程概述

软件开发生命周期 软件定义时期&#xff1a;包括可行性研究和详细需求分析&#xff0c;任务是确定软件开发的总目标。 问题定义可行性研究&#xff08;经济、技术、操作、社会可行性&#xff0c;确定问题和解决办法&#xff09;需求分析&#xff08;确定功能需求&#xff0c;性…...

文件系统 linux ─── 第19课

前面博客讲解的是内存级文件管理,接下来介绍磁盘级文件管理 文件系统分为两部分 内存级文件系统 : OS加载进程 ,进程打开文件, OS为文件创建struct file 和文件描述符表 ,将进程与打开的文件相连, struct file 内还函数有指针表, 屏蔽了底层操作的差异,struct file中还有内核级…...

一篇博客搞定时间复杂度

时间复杂度 1、什么是时间复杂度&#xff1f;2、推导大O的规则3、时间复杂度的计算3.1 基础题 13.2 基础题 23.3基础题 33.4进阶题 13.5进阶题 23.6 偏难题 13.7偏难题 2&#xff08;递归&#xff09; 前言&#xff1a; 算法在编写成可执行程序后&#xff0c;运行时要耗费时间和…...

微信小程序实现根据不同的用户角色显示不同的tabbar并且可以完整的切换tabbar

直接上图上代码吧 // login/login.js const app getApp() Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {},/*** 生命周期函…...

S_on@atwk的意思

S_onatwk 可能是某种自动化或控制系统中的符号或标记&#xff0c;尤其在PLC&#xff08;可编程逻辑控制器&#xff09;编程中&#xff0c;类似的表达方式通常用于表示特定的信号、状态或操作。 我们可以分析这个表达式的各个部分&#xff1a; S_on&#xff1a;通常&#xff0…...

Liunx启动kafka并解决kafka时不时挂掉的问题

kafka启动步骤 先启动zookeeper&#xff0c;启动命令如下 nohup ./zookeeper-server-start.sh /home/kafka/kafka/config/zookeeper.properties > /home/kafka/kafka/zookeeper.log 2>&1 &再启动kafka&#xff0c;启动命令如下 nohup ./kafka-server-start.sh…...

16 | 实现简洁架构的 Store 层

提示&#xff1a; 所有体系课见专栏&#xff1a;Go 项目开发极速入门实战课&#xff1b;欢迎加入 云原生 AI 实战 星球&#xff0c;12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力&#xff08;聚焦于 Go、云原生、AI Infra&#xff09;&#xff1b;本节课最终…...

华为hcia——Datacom实验指南——以太网帧和IPV4数据包格式(一)

实验开始 第一步配置环境 第二步配置客户端 如图所示&#xff0c;我们把客户端的ip配置成192.168.1.10&#xff0c;网关设为192.168.1.1 第三步配置交换机1 system-view sysname LSW1 vlan batch 10 interface ethernet0/0/1 port link-type access port default vlan 10 qu…...

ubuntu软件——视频、截图、图片、菜单自定义等

视频软件&#xff0c;大部分的编码都能适应 sudo apt install vlc图片软件 sudo apt install gwenview截图软件 sudo apt install flameshot设置快捷键 flameshot flameshot gui -p /home/cyun/Pictures/flameshot也就是把它保存到一个自定义的路径 菜单更换 sudo apt r…...

CSS中z-index使用详情

定位层级 1.定位元素的显示层级比普通元素高,无论什么定位,显示层级都是一样的; 2.如果位置发生重叠,默认情况是:后面的元素,会显示在前面元素之上; 3.可以通过CSS属性z-index调整元素的显示层级; 4.z-index的属性值是数字,没有单位,值越大显示层级越高; 5.只有定位的元素…...

qt 自带虚拟键盘的编译使用记录

一、windows 下编译 使用vs 命令窗口&#xff0c;分别执行&#xff1a; qmake CONFIG"lang-en_GB lang-zh_CN" nmake nmake install 如果事先没有 指定需要使用的输入法语言就进行过编译&#xff0c;则需要先 执行 nmake distclean 清理后执行 qmake 才能生效。 …...

杨辉三角形(信息学奥赛一本通-2043)

【题目描述】 例5.11 打印杨辉三角形的前n(2≤n≤20)行。杨辉三角形如下图&#xff1a; 当n5时 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 输出&#xff1a; 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 【输入】 输入行数n。 【输出】 输出如题述三角形。n行&#…...

CentOS 7 系统上安装 SQLite

1. 检查系统更新 在安装新软件之前&#xff0c;建议先更新系统的软件包列表&#xff0c;以确保使用的是最新的软件源和补丁。打开终端&#xff0c;执行以下命令&#xff1a; sudo yum update -y -y 选项表示在更新过程中自动回答 “yes”&#xff0c;避免手动确认。 2. 安装 …...

程序化广告行业(13/89):DSP的深入解析与运营要点

程序化广告行业&#xff08;13/89&#xff09;&#xff1a;DSP的深入解析与运营要点 大家好&#xff01;一直以来&#xff0c;我都对程序化广告行业保持着浓厚的学习兴趣&#xff0c;在探索的过程中积累了不少心得。今天就想把这些知识分享出来&#xff0c;和大家一起学习进步…...

使用 Doris 和 LakeSoul

作为一种全新的开放式的数据管理架构&#xff0c;湖仓一体&#xff08;Data Lakehouse&#xff09;融合了数据仓库的高性能、实时性以及数据湖的低成本、灵活性等优势&#xff0c;帮助用户更加便捷地满足各种数据处理分析的需求&#xff0c;在企业的大数据体系中已经得到越来越…...

datax源码分析

文章目录 前言一、加载配置文件二、根据加载的配置文件进行调度三、根据配置文件执行读取写入任务总结 前言 在上一篇文章当中我们已经了解了datax的启动原理&#xff0c;以及datax的最基础的配置&#xff0c;datax底层java启动类的入口及关键参数。 接下来我将进行启动类执行…...

【HDLbits--分支预测器简单实现】

HDLbits--分支预测器简单实现 1 timer2.branche predicitors3.Branch history shift4.Branch direction predictor 以下是分支预测器的简单其实现&#xff1b; 1 timer 实现一个计时器&#xff0c;当load1’b1时&#xff0c;加载data进去&#xff0c;当load1’b0时进行倒计时&…...

优化Go错误码管理:构建清晰、优雅的HTTP和gRPC错误码规范

在系统开发过程中&#xff0c;如何优雅地管理错误信息一直是个棘手问题。传统的错误处理方式往往存在不统一、难以维护等缺点。而 errcode 模块通过对错误码进行规范化管理&#xff0c;为系统级和业务级错误提供了统一的编码标准。本文将带您深入了解 errcode 的设计原理、错误…...

批量压缩与优化 Excel 文档,减少 Excel 文档大小

当我们在 Excel 文档中插入图片资源的时候&#xff0c;如果我们插入的是原图&#xff0c;可能会导致 Excel 变得非常的大。这非常不利于我们传输或者共享。那么当我们的 Excel 文件非常大的时候&#xff0c;我们就需要对文档做一些压缩或者优化的处理。那有没有什么方法可以实现…...

MongoDB分页实现方式对比:PageRequest vs Skip/Limit

MongoDB分页实现方式对比&#xff1a;PageRequest vs Skip/Limit 一、基本概念1.1 PageRequest分页1.2 Skip/Limit分页 二、主要区别2.1 使用方式2.2 参数计算2.3 适用场景PageRequest适用场景&#xff1a;Skip/Limit适用场景&#xff1a; 三、性能考虑3.1 PageRequest的性能特…...

SAP Commerce(Hybris)营销模块(一):商城产品折扣配置

基于Hybris的Backoffice后台管理系统&#xff0c;创建一个基于模板的营销规则&#xff0c;并配置上对应的优惠活动。 架构设计 先从一张架构图说起 Hybris的促销模块&#xff0c;是基于Promotion引擎来实现的&#xff0c;可以通过Backoffice来进行配置。 通过上面的架构图又可…...

如何在 React 中实现错误边界?

在 React 中实现错误边界 错误边界是 React 提供的一种机制&#xff0c;用于捕获子组件树中的 JavaScript 错误&#xff0c;并展示回退 UI。它可以帮助开发者更好地处理错误&#xff0c;提升用户体验。本文将详细介绍如何在 React 中实现错误边界&#xff0c;包括其工作原理、…...

从头开始开发基于虹软SDK的人脸识别考勤系统(python+RTSP开源)(五)完整源码已上传!

本篇是对照之前代码剩余的部分代码做补充&#xff0c;分享给大家&#xff0c;便于对照运行测试。 完整版的全功能单文件版本已上传&#xff01;https://download.csdn.net/download/xiaomage_cn/90484179 人脸识别抽象层&#xff0c;这个大家应该都知道&#xff0c;就是为了方…...

PySide(PyQT)的mouseMoveEvent()和hoverMoveEvent()的区别

在 PySide中&#xff0c;mouseMoveEvent 和 hoverMoveEvent 都是用于处理鼠标移动相关操作的事件&#xff0c;但它们之间存在明显的区别&#xff1a; 事件触发条件 • mouseMoveEvent&#xff1a; 当鼠标在对应的图形项&#xff08;如 QGraphicsPixmapItem&#xff09…...

【通缩螺旋的深度解析与科技破局路径】

通缩螺旋的深度解析与科技破局路径 一、通缩螺旋的形成机制与恶性循环 通缩螺旋&#xff08;Deflationary Spiral&#xff09;是经济学中描述价格持续下跌与经济衰退相互强化的动态过程&#xff0c;其核心逻辑可拆解为以下链条&#xff1a; 需求端萎缩&#xff1a;居民消费信…...

【如何使用云服务器与API搭建专属聊天系统:宝塔面板 + Openwebui 完整教程】

文章目录 不挑电脑、不用技术&#xff0c;云服务器 API 轻松搭建专属聊天系统&#xff0c;对接 200 模型&#xff0c;数据全在自己服务器&#xff0c;安全超高一、前置准备&#xff1a;3 分钟快速上手指南云服务器准备相关账号注册 二、手把手部署教程&#xff08;含代码块&a…...

Oracle数据库存储结构--逻辑存储结构

数据库存储结构&#xff1a;分为物理存储结构和逻辑存储结构。 物理存储结构&#xff1a;操作系统层面如何组织和管理数据 逻辑存储结构&#xff1a;Oracle数据库内部数据组织和管理数据&#xff0c;数据库管理系统层面如何组织和管理数据 Oracle逻辑存储结构 数据库的逻…...

C++ 左值(lvalue)和右值(rvalue)

在 C 中&#xff0c;左值&#xff08;lvalue&#xff09;和右值&#xff08;rvalue&#xff09;是指对象的不同类别&#xff0c;区分它们对于理解 C 中的表达式求值和资源管理非常重要&#xff0c;尤其在现代 C 中涉及到移动语义&#xff08;Move Semantics&#xff09;和完美转…...

《实战AI智能体》DeepSearcher 的架构设计

DeepSearcher 的架构设计 一个通往搜索AGI的Agentic RAG应该如何设计&#xff1f; 从架构上看&#xff0c;DeepSearcher 主要分为两大模块。 一个是数据接入模块&#xff0c;通过Milvus向量数据库来接入各种第三方的私有知识。这也是DeepSearcher相比OpenAI的原本DeepResearc…...

Kotlin 继承

Kotlin 继承 概述 Kotlin 是一种现代的编程语言&#xff0c;它具有简洁、安全、互操作性等特点。在面向对象编程中&#xff0c;继承是一种非常重要的特性&#xff0c;它允许我们创建具有共同属性和方法的类。本文将详细介绍 Kotlin 中的继承机制&#xff0c;包括继承的基本概…...

【6】树状数组学习笔记

前言 树状数组是我学的第一个高级数据结构&#xff0c;属于 log ⁡ \log log 级数据结构。 其实现在一般不会单独考察数据结构&#xff0c;主要是其在其他算法&#xff08;如贪心&#xff0c;DP&#xff09;中起到优化作用。 长文警告&#xff1a;本文一共 995 995 995 行…...

【RISCV LAB】0x01-安装实验仿真辅助工具

安装实验辅助工具 实验环境搭建安装 Verilator编译依赖下载源码编译安装测试安装 安装 RISC-V 交叉编译工具链编译依赖下载源码编译安装编译并安装添加环境变量并测试 安装 GTKWave其他模拟器推荐RARSemulsiV FAQ 实验环境搭建 Verilator 是一款开源的支持 Verilog 和 SystemV…...

OSPF-2 邻接建立关系

上一期我们说了OSPF的邻居建立关系以及OSPF邻居关系建立中建立失败的因素以及相关实验案例 这一期我们来说说OSPF的邻接关系建立时需要交互哪些报文以及失败因素及原因和相关实验案例 一、概述 在运行了OSPF的网络当中为了交互链路状态信息和路由信息,互相之间需要建立邻接关…...

操作系统知识点29

1.当用户使用外部设备时&#xff0c;其控制设备的命令传递途径依次为用户应用层->设备独立层->设备驱动层->设备硬件 2.通常用于管理空闲物理内存的方法&#xff1a;空闲快链表法&#xff1b;位示图法&#xff1b;空闲页面表 3. 可用于文件的存取控制和保护的方法&a…...