react 组件应用
文章目录
- react 组件
- react 中组件 hook 函数应用
- useMemo
- 技术细节(useMemo 钩子函数和 useCallback 钩子函数)
- 小结(依赖性数组应用)
react 组件
-
函数式组件实例及应用场景
- 实例:
- 以下是一个简单的函数式组件,用于显示一个欢迎消息。
import React from 'react'; const WelcomeMessage = (props) => {return <h1>Welcome, {props.name}!</h1>; }; export default WelcomeMessage;
- 这个组件接收一个名为
name
的属性(props
),并在h1
标签中显示欢迎消息。它可以在其他组件中被这样使用:
import React from 'react'; import WelcomeMessage from './WelcomeMessage'; const App = () => {return (<div><WelcomeMessage name="John" /></div>); }; export default App;
- 应用场景:
- 展示型组件:函数式组件非常适合用于展示型组件,这些组件主要用于将数据以某种形式展示给用户,没有复杂的内部状态或生命周期方法。例如,一个简单的文章列表组件,它接收文章数据作为属性,然后将每篇文章的标题、作者等信息展示出来。
- 无状态逻辑组件:当组件不需要维护自己的状态,只是简单地根据传入的属性进行渲染时,函数式组件是很好的选择。像上面的欢迎消息组件,它只是根据传入的名字属性来显示消息,没有自己的内部状态。
- 作为纯函数:函数式组件就像纯函数一样,对于相同的输入(属性),总是返回相同的输出(渲染结果)。这使得它们在性能优化方面具有优势,因为React可以更容易地判断组件是否需要重新渲染。例如,在一个数据可视化组件中,只要传入的数据(属性)没有变化,组件就不需要重新渲染。
- 实例:
-
类组件实例及应用场景
- 实例:
- 下面是一个简单的类组件,用于实现一个计数器。
import React, { Component } from 'react'; class Counter extends Component {constructor(props) {super(props);this.state = {count: 0};}increment() {this.setState((prevState) => ({count: prevState.count + 1}));}render() {return (<div><p>Count: {this.state.count}</p><button onClick={() => this.increment()}>Increment</button></div>);} } export default Counter;
- 这个类组件有一个内部状态
count
,初始值为0。有一个increment
方法用于增加计数,在render
方法中,它展示当前的计数,并提供一个按钮,点击按钮会调用increment
方法来更新状态,从而重新渲染组件显示新的计数。
- 应用场景:
- 有状态组件:类组件适合需要维护内部状态的场景。例如,在一个表单组件中,需要跟踪用户输入的各个字段的值,这些值就是组件的内部状态。像一个登录表单,需要记录用户输入的用户名和密码,并且可能还需要验证输入是否符合要求,这时候类组件的状态管理就很有用。
- 复杂的生命周期管理:当组件需要在挂载、更新或卸载等不同生命周期阶段执行特定操作时,类组件是更好的选择。例如,在组件挂载时获取数据,在组件更新时根据新的数据重新计算某些值,在组件卸载时清理资源(如取消网络请求、清除定时器等)。比如,一个地图组件,在挂载时需要初始化地图,在更新时可能需要更新地图上的标记位置,在卸载时需要释放地图相关的资源,使用类组件可以更好地利用生命周期方法来实现这些功能。
- 与第三方库集成:如果需要在组件中集成第三方库,并且这些库需要与组件的生命周期进行交互,类组件会更方便。例如,在使用一些动画库时,可能需要在组件挂载时启动动画,在组件卸载时停止动画,通过类组件的生命周期方法可以很好地控制这些操作。
- 实例:
react 中组件 hook 函数应用
-
React组件传值
- 父组件向子组件传值(Props)
- 实例:
- 首先创建一个父组件
ParentComponent
和一个子组件ChildComponent
。
import React from 'react'; import ChildComponent from './ChildComponent'; const ParentComponent = () => {const message = "Hello from Parent";return (<div><ChildComponent passedMessage={message} /></div>); }; export default ParentComponent;
- 子组件接收
passedMessage
属性并显示它。
import React from 'react'; const ChildComponent = (props) => {return (<div><p>{props.passedMessage}</p></div>); }; export default ChildComponent;
- 首先创建一个父组件
- 解释:在父组件中,定义了一个变量
message
,然后将这个变量作为属性passedMessage
传递给子组件ChildComponent
。在子组件中,通过props.passedMessage
来访问这个传递过来的值,并将其渲染在p
标签中。
- 实例:
- 子组件向父组件传值(回调函数)
- 实例:
- 父组件定义一个函数来接收子组件传递的值。
import React from 'react'; import ChildComponentWithCallback from './ChildComponentWithCallback'; const ParentComponentWithCallback = () => {const handleChildValue = (valueFromChild) => {console.log("Received value from child: ", valueFromChild);};return (<div><ChildComponentWithCallback sendValueToParent={handleChildValue} /></div>); }; export default ParentComponentWithCallback;
- 子组件调用父组件传递过来的函数来传递值。
import React from 'react'; const ChildComponentWithCallback = (props) => {const valueToSend = "Value from Child";const sendValue = () => {props.sendValueToParent(valueToSend);};return (<div><button onClick={sendValue}>Send Value to Parent</button></div>); }; export default ChildComponentWithCallback;
- 解释:在父组件中,
handleChildValue
函数用于接收子组件传递的值。这个函数作为属性sendValueToParent
传递给子组件。在子组件中,当按钮被点击时,sendValue
函数被调用,它会调用props.sendValueToParent
并将valueToSend
作为参数传递,这样就实现了子组件向父组件传值。
- 实例:
- 父组件向子组件传值(Props)
-
Hook函数应用实例
- useState Hook
- 实例:
- 用于在函数式组件中添加状态。
import React, { useState } from 'react'; const CounterHook = () => {const [count, setCount] = useState(0);const increment = () => {setCount(count + 1);};return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button></div>); }; export default CounterHook;
- 解释:
useState
是一个Hook函数,它返回一个数组,数组的第一个元素是状态变量(count
),第二个元素是用于更新这个状态变量的函数(setCount
)。初始状态值为0。当按钮被点击时,increment
函数被调用,它使用setCount
来更新count
的值,从而导致组件重新渲染并显示新的计数。
- 实例:
- useEffect Hook
- 实例:
- 用于在组件挂载、更新或卸载时执行副作用操作,如获取数据、订阅事件等。
import React, { useState, useEffect } from 'react'; const DataFetchingComponent = () => {const [data, setData] = useState([]);useEffect(() => {const fetchData = async () => {const response = await fetch('https://example.com/api/data');const jsonData = await response.json();setData(jsonData);};fetchData();}, []);return (<div>{data.map((item) => (<p key={item.id}>{item.name}</p>))}</div>); }; export default DataFetchingComponent;
- 解释:
useEffect
接受一个函数作为参数。在这个例子中,函数内部定义了一个异步函数fetchData
来从API获取数据。获取到数据后,使用setData
来更新状态。第二个参数[]
表示这个useEffect
只在组件挂载时执行一次。如果省略这个参数,useEffect
会在组件每次更新时都执行。如果想在某些特定状态变化时执行useEffect
,可以将这些状态变量放在数组中,例如[count]
,这样当count
状态改变时,useEffect
就会执行。
- 实例:
- useContext Hook
- 实例:
- 用于在组件树中共享数据,避免了层层传递属性的麻烦。
- 首先创建一个上下文(Context)。
import React from 'react'; const MyContext = React.createContext();
- 然后在一个父组件中提供这个上下文的值。
import React from 'react'; import MyContext from './MyContext'; import ChildComponentUsingContext from './ChildComponentUsingContext'; const ParentComponentWithContext = () => {const sharedValue = "This is a shared value";return (<MyContext.Provider value={sharedValue}><ChildComponentUsingContext /></MyContext.Provider>); }; export default ParentComponentWithContext;
- 最后在子组件中使用
useContext
来获取这个共享的值。
import React, { useContext } from 'react'; import MyContext from './MyContext'; const ChildComponentUsingContext = () => {const sharedValue = useContext(MyContext);return (<div><p>{sharedValue}</p></div>); }; export default ChildComponentUsingContext;
- 解释:
React.createContext
创建了一个上下文对象。在ParentComponentWithContext
中,通过MyContext.Provider
来提供一个共享的值sharedValue
。在ChildComponentUsingContext
中,useContext(MyContext)
用于获取这个共享的值,并将其渲染在p
标签中。这样,无论组件层次有多深,只要在MyContext.Provider
的范围内,都可以方便地获取这个共享值。
- 实例:
- useState Hook
useMemo
-
基本概念
useMemo
是一个React Hook,它用于缓存计算结果。其主要目的是通过记忆(memorization)来避免在每次组件重新渲染时都进行昂贵的计算。这样可以优化性能,特别是当计算过程复杂或者依赖的数据频繁变化时。
-
语法和参数
- 语法:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- 第一个参数是一个函数,这个函数包含了需要进行记忆化的计算。例如,这个函数可能是对一个大型数组进行过滤、排序或者其他复杂的操作。
- 第二个参数是一个依赖项数组。这个数组中的元素是当它们发生变化时,
useMemo
才会重新运行第一个参数中的计算函数,以更新memoizedValue
。如果依赖项数组为空,那么计算函数只会在组件初次渲染时执行一次。
- 语法:
-
应用实例
- 避免重复计算
- 假设我们有一个组件,用于计算并显示一个非常大的斐波那契数列。斐波那契数列的计算是比较复杂的,而且如果没有优化,每次组件渲染都会重新计算整个数列。
import React, { useState, useMemo } from 'react'; const FibonacciCalculator = () => {const [n, setN] = useState(10);// 使用useMemo来缓存斐波那契数列的计算结果const fibonacciSequence = useMemo(() => {const sequence = [0, 1];for (let i = 2; i <= n; i++) {sequence.push(sequence[i - 1] + sequence[i - 2]);}return sequence;}, [n]);return (<div><inputtype="number"value={n}onChange={(e) => setN(Number(e.target.value))}/><p>斐波那契数列前{n}项: {fibonacciSequence.join(', ')}</p></div>); }; export default FibonacciCalculator;
- 解释:在这个组件中,
useMemo
用于缓存斐波那契数列的计算结果。当n
的值发生变化时(通过输入框改变n
的值),useMemo
会重新运行计算斐波那契数列的函数,因为n
是useMemo
的依赖项。如果n
没有变化,即使组件因为其他原因(比如父组件重新渲染)重新渲染,fibonacciSequence
的值也不会重新计算,而是直接使用之前缓存的值。
- 优化子组件渲染
- 考虑一个场景,父组件有一个状态值,这个状态值会导致父组件频繁重新渲染,但是子组件只有在特定数据变化时才需要重新渲染。
import React, { useState, useMemo } from 'react'; const ParentComponent = () => {const [count, setCount] = useState(0);const [data, setData] = useState([1, 2, 3]);// 假设这是一个复杂的计算,用于过滤数据const filteredData = useMemo(() => {return data.filter((item) => item > 1);}, [data]);return (<div><button onClick={() => setCount(count + 1)}>Increment Count (This causes Parent to re - render)</button><ChildComponent data={filteredData} /></div>); }; const ChildComponent = ({ data }) => {return (<div>{data.map((item) => (<p key={item}>{item}</p>))}</div>); }; export default ParentComponent;
- 解释:在
ParentComponent
中,count
状态的变化会导致父组件重新渲染。但是,通过useMemo
缓存了filteredData
的计算结果,只要data
没有变化,filteredData
就不会重新计算,传递给ChildComponent
的数据也不会改变。这样,即使父组件因为count
的变化重新渲染,ChildComponent
也不会重新渲染,除非data
发生变化,从而优化了子组件的渲染性能。
- 避免重复计算
技术细节(useMemo 钩子函数和 useCallback 钩子函数)
-
基本概念和用途
- useMemo:
- 主要用于缓存计算结果。它会记住一个函数的返回值,只有当依赖项发生变化时,才会重新计算这个返回值。这个返回值可以是任何类型的数据,比如一个复杂的计算结果、一个经过处理的数据数组等。
- 目的是避免在每次组件渲染时都进行昂贵的计算,以提高性能。
- useCallback:
- 用于缓存函数本身。它返回一个记忆化(memoized)的函数,只有当依赖项发生变化时,这个记忆化的函数才会重新创建。
- 通常用于在组件中传递回调函数,以避免在不必要的情况下重新创建函数,从而防止子组件因为接收到新的函数引用而重新渲染。
- useMemo:
-
语法对比
- useMemo:
- 语法:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- 第一个参数是一个返回需要缓存的值的函数,第二个参数是一个依赖项数组,用于确定何时重新计算这个值。
- 语法:
- useCallback:
- 语法:
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);
- 第一个参数是需要缓存的函数本身,第二个参数同样是依赖项数组,用于决定何时重新创建这个函数。
- 语法:
- useMemo:
-
应用场景对比
- useMemo:
- 复杂计算的缓存:
- 例如,在一个数据可视化组件中,需要对大量的数据进行复杂的统计计算,如计算平均值、标准差等。
import React, { useState, useMemo } from 'react'; const DataVisualizationComponent = () => {const [data, setData] = useState([1, 2, 3, 4, 5]);// 计算平均值并缓存结果const average = useMemo(() => {const sum = data.reduce((acc, val) => acc + val, 0);return sum / data.length;}, [data]);return (<div><p>数据平均值: {average}</p></div>); }; export default DataVisualizationComponent;
- 解释:每次
data
发生变化时,useMemo
会重新计算平均值;如果data
不变,即使组件因为其他原因重新渲染,也会直接使用缓存的平均值,避免了重复计算。
- 避免数据处理的重复执行:
- 假设要对一个文本字符串进行复杂的格式化操作,如将一段包含HTML标签的文本转换为纯文本并进行单词计数。
import React, { useState, useMemo } from 'react'; const TextProcessingComponent = () => {const [text, setText] = useState("<p>Hello, World!</p>");// 缓存格式化后的文本和单词计数结果const [formattedText, wordCount] = useMemo(() => {const plainText = text.replace(/<[^>]*>/g, "");const words = plainText.split(" ").length;return [plainText, words];}, [text]);return (<div><p>格式化后的文本: {formattedText}</p><p>单词计数: {wordCount}</p></div>); }; export default TextProcessingComponent;
- 解释:
useMemo
确保只有当text
发生变化时,才会重新进行文本格式化和单词计数操作。
- 复杂计算的缓存:
- useCallback:
- 优化子组件渲染(传递回调函数):
- 考虑一个包含列表和删除按钮的组件,点击删除按钮会调用一个回调函数来删除列表中的某个元素。
import React, { useState, useCallback } from 'react'; const ParentListComponent = () => {const [list, setList] = useState([1, 2, 3]);// 记忆化删除函数const handleDelete = useCallback((index) => {const newList = [...list];newList.splice(index, 1);setList(newList);}, [list]);return (<div>{list.map((item, index) => (<ChildListItem key={item} item={item} onDelete={handleDelete(index)} />))}</div>); }; const ChildListItem = ({ item, onDelete }) => {return (<div><p>{item}</p><button onClick={onDelete}>删除</button></div>); }; export default ParentListComponent;
- 解释:
useCallback
用于缓存handleDelete
函数。只有当list
发生变化时,handleDelete
函数才会重新创建。这样,在ParentListComponent
重新渲染时,如果list
没有变化,传递给ChildListItem
的onDelete
函数引用不会改变,从而避免了ChildListItem
因为函数引用改变而不必要地重新渲染。
- 事件处理函数的优化:
- 例如,在一个游戏组件中有多个按钮,每个按钮都有自己的点击事件处理函数,这些函数可能会根据游戏状态(如得分、关卡等)进行一些操作。
import React, { useState, useCallback } from 'react'; const GameComponent = () => {const [score, setScore] = useState(0);const [level, setLevel] = useState(1);// 记忆化加分事件处理函数const handleAddScore = useCallback(() => {setScore(score + 10);}, [score]);// 记忆化升级事件处理函数const handleLevelUp = useCallback(() => {setLevel(level + 1);}, [level]);return (<div><button onClick={handleAddScore}>加分</button><button onClick={handleLevelUp}>升级</button></div>); }; export default GameComponent;
- 解释:
useCallback
确保每个事件处理函数只有在其依赖的游戏状态(score
或level
)发生变化时才会重新创建。这有助于在游戏状态更新时,只重新渲染与状态变化相关的部分,提高性能。
- 优化子组件渲染(传递回调函数):
- useMemo:
小结(依赖性数组应用)
-
理解依赖项数组的作用
- 在
useMemo
、useCallback
和其他类似的React钩子(如useEffect
)中,依赖项数组用于告诉React在哪些值发生变化时,需要重新执行相关的操作。例如,在useMemo
中,当依赖项数组中的元素变化时,会重新计算缓存的值;在useCallback
中,依赖项的变化会导致回调函数重新创建。
- 在
-
分析组件内部的逻辑和状态使用情况
- 数据读取与计算
- 识别使用的数据:仔细查看在计算或函数内部使用了哪些变量、状态(
state
)或属性(props
)。例如,在一个useMemo
钩子中,如果是计算一个购物车商品总价,并且总价是根据商品数量和单价来计算的,那么商品数量和单价就是依赖项。 - 考虑数据来源:如果数据来自组件的状态(通过
useState
定义)、父组件传递的属性(props
)或者其他外部数据源(如context
),这些都有可能是依赖项。例如,在一个展示用户信息的组件中,用户的姓名、年龄等属性是从父组件传递过来的,那么这些props
就应该在依赖项数组中,因为如果这些信息改变,组件的展示可能需要更新。
- 识别使用的数据:仔细查看在计算或函数内部使用了哪些变量、状态(
- 函数调用与副作用操作
- 检查函数内部调用的函数:如果在
useCallback
定义的函数内部调用了其他函数,并且这些函数的行为可能因为某些数据的变化而改变,那么这些数据对应的变量也可能是依赖项。例如,在一个表单提交的回调函数中,调用了一个验证表单数据的函数,而验证函数可能依赖于表单的某些字段,这些字段对应的变量就是依赖项。 - 副作用操作相关的数据:对于
useEffect
钩子,考虑在其中执行的副作用操作(如数据获取、订阅事件等)依赖于哪些数据。如果在组件挂载时通过fetch
获取数据,并且数据的URL是根据某个状态变量确定的,那么这个状态变量就是useEffect
的依赖项。
- 检查函数内部调用的函数:如果在
- 数据读取与计算
-
遵循最小化依赖原则
- 只包含真正会影响计算或操作的元素。例如,在一个简单的计数器组件中,有一个
increment
函数用于增加计数,一个doubleCount
函数(通过useMemo
缓存)用于计算计数的两倍。doubleCount
函数只依赖于计数变量,而不依赖于increment
函数,所以在useMemo
的依赖项数组中只需要包含计数变量。 - 避免包含不必要的元素,因为这可能导致过度重新计算或重新创建函数。如果不小心包含了一个不会影响操作的变量,那么每次这个变量变化时,都会触发不必要的重新计算或重新创建,降低性能。例如,在一个组件中,有一个用于显示当前日期的函数(通过
useMemo
缓存),这个函数只依赖于日期相关的状态,而不依赖于一个用于切换主题的变量,那么主题变量就不应该出现在useMemo
的依赖项数组中。
- 只包含真正会影响计算或操作的元素。例如,在一个简单的计数器组件中,有一个
-
动态依赖项的情况
- 有时候依赖项可能是动态生成的,例如,一个根据用户权限动态加载不同模块的组件。在这种情况下,可以考虑使用一个更高级的技术,如使用
useReducer
来管理状态,或者在useEffect
中动态地添加和移除事件监听器,并且根据具体情况更新依赖项数组。但是这种情况比较复杂,需要谨慎处理,因为不当的操作可能导致内存泄漏或其他性能问题。 - 如果依赖项是一个对象或数组,并且对象或数组的内容可能会改变而引用不变(例如,修改对象的属性而不是重新创建对象),React可能无法正确检测到变化。在这种情况下,可以考虑使用一些辅助函数,如
React.useMemo
来创建一个新的引用,或者使用Object.assign
或[...array]
等方式来创建新的对象或数组,并且将这些新的引用作为依赖项。
- 有时候依赖项可能是动态生成的,例如,一个根据用户权限动态加载不同模块的组件。在这种情况下,可以考虑使用一个更高级的技术,如使用
相关文章:

react 组件应用
文章目录 react 组件react 中组件 hook 函数应用useMemo技术细节(useMemo 钩子函数和 useCallback 钩子函数)小结(依赖性数组应用) react 组件 函数式组件实例及应用场景 实例: 以下是一个简单的函数式组件,用于显示一个欢迎消息。 import React from re…...

mysql 快速解决死锁方式
mysql 快速解决死锁方式 直接寻找并终止导致死锁的具体 SQL 语句是处理死锁的一种有效方法,特别是在高并发环境中。以下步骤和示例展示了如何通过识别、分析和终止长时间运行的 SQL 语句来解决死锁问题。 一、识别那个导致死锁的 SQL 语句 1. 使用 SHOW ENGINE I…...

RabbitMQ 篇-深入了解 RabbitMQ 安装以及 SpringAMQP 的基础使用(声明队列和交换机、发送接收消息、配置 JSON 消息转化器)
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 RabbitMQ 初识 1.1 RabbitMQ 安装 2.0 数据隔离 2.1 用户管理 2.2 virtual host 虚拟主机 3.0 SpringAMQP 3.1 RabbitMQ 配置 3.2 发送消息 3.3 接收消息 3.4 Wor…...

在 WPF 中,绑定机制是如何工作的?WPF数据绑定机制解析
在WPF(Windows Presentation Foundation)中,数据绑定机制是其核心功能之一,广泛用于连接应用程序的UI(用户界面)和应用程序的业务逻辑层。数据绑定允许你将UI元素与数据源(如对象、集合或其他数…...

pwn学习笔记(12)--Chunk Extend and Overlapping
pwn学习笔记(12)–Chunk Extend and Overlapping chunk extend 是堆漏洞的一种常见利用手法,通过 extend 可以实现 chunk overlapping(块重叠) 的效果。这种利用方法需要以下的时机和条件: 程序中存在…...

java基础面试题六集合框架
目录 1. List,Set,Map是否继承自collection接口? 2. 说说List,Set,Map三者的区别 3. 写出list、map、set接口的实现类,并说出其特点 4. 常见集合类的区别和适用场景 5. 集合的父类是谁?哪些安全的? 6…...

2024年12月一区SCI-指数-三角优化算法ETO-附Matlab免费代码
引言 本期介绍了一种基于数学概念的元启发式优化算法,称为指数-三角优化算法Exponential-trigonometric optimization algorithm,ETO。该算法基于指数函数和三角函数的复杂组合,于2024年12月最新发表在中JCR1区、 中科院1区 SCI期刊Computer…...

设置服务器ssh连接超时时间
在Linux服务器上,您可以通过修改SSH服务器配置文件来设置SSH连接的超时时间。以下是设置SSH连接超时时间的一些步骤: 打开SSH服务器配置文件。这个文件通常是/etc/ssh/sshd_config。sudo nano /etc/ssh/sshd_config在配置文件中,您可以设置以…...

Dubbo分布式日志跟踪实现
前言 随着越来越多的应用逐渐微服务化后,分布式服务之间的RPC调用使得异常排查的难度骤增,最明显的一个问题,就是整个调用链路的日志不在一台机器上,往往定位问题就要花费大量时间。如何在一个分布式网络中把单次请求的整个调用日…...

EPSON机械手与第三方相机的校准功能设计By python
EPSON机械手与第三方相机的校准功能设计By python 使用Python来实现EPSON机械手与第三方相机的校准功能是一个复杂但可行的任务。这通常涉及以下几个步骤:硬件接口通信、图像处理、标定算法实现和控制逻辑编写。 1. 环境准备 首先,库 pip install numpy opencv-python pyse…...

探索 Java 23:新时代的编程利器
一、引言 随着技术的不断发展,Java 作为一种广泛应用的编程语言也在不断演进。Java 23 的推出带来了许多令人兴奋的新特性和改进,为开发者提供了更多的工具和功能,以应对日益复杂的软件开发挑战。本文将深入介绍 Java 23 的各个方面。 二、J…...

CSS3_3D变换(七)
1、CSS3_3D变换 1.1 3D空间与景深 3D空间:在父元素中将属性transform-style设置为preserve-3d开启3D空间,默认值为flat(开启2D空间); 景深:人眼与平面的距离,产生透视效果,使得效果…...

Mesh网格
Mesh(网格) 定义:Mesh 是一个包含顶点、三角形、顶点法线、UV坐标、颜色和骨骼权重等数据的对象。它定义了3D模型的几何形状。 功能: 顶点(Vertices):构成3D模型的点。 三角形(Triangles)&…...

LeetCode 509.斐波那契数
动态规划思想 五步骤: 1.确定dp[i]含义 2.递推公式 3.初始化 4.遍历顺序 5.打印dp数组 利用状态压缩,简化空间复杂度。在原代码中,dp 数组保存了所有状态,但实际上斐波那契数列的计算只需要前两个状态。因此,我们…...

SQL Server 数据太多如何优化
大家好,我是 V 哥。讲了很多数据库,有小伙伴说,SQL Server 也讲一讲啊,好吧,V 哥做个听话的门童,今天要聊一聊 SQL Server。 在 SQL Server 中,当数据量增大时,数据库的性能可能会受…...

关于word 页眉页脚的一些小问题
去掉页眉底纹: 对文档的段落边框和底纹进行设置,也是页眉横线怎么删除的一种解决方式,具体操作如下: 选中页眉中的横线文本; 点击【开始】选项卡,在【段落】组中点击【边框】按钮的下拉箭头; …...

【高等数学学习记录】连续函数的运算与初等函数的连续性
一、知识点 (一)连续函数的和、差、积、商的连续性 定理1 设函数 f ( x ) f(x) f(x) 和 g ( x ) g(x) g(x) 在点 x 0 x_0 x0 连续,则它们的和(差) f g f\pm g fg、积 f ⋅ g f\cdot g f⋅g 及商 f g \frac{f…...

【抖音直播间弹幕】protobuf协议分析
将Uint8Array变成 PushFrame格式,里面的payload就存放着弹幕消息 点进去就可以看到其定义的proto结构 headers是一个自定义类型 将测试数据保存一下,等下做对比 先将PushFrame的 payload 内容进行gzip解压 然后再解析为响应 可以看到里面有对应的消…...

Swift 开发教程系列 - 第11章:内存管理和 ARC(Automatic Reference Counting)
在 Swift 中,内存管理由 ARC(自动引用计数)机制自动处理。ARC 通过追踪和管理对象的引用计数来确保分配的内存得到有效释放。尽管 ARC 在大多数情况下能够高效地管理内存,但理解其工作原理仍然十分重要,因为不当的引用…...

C#中 layout的用法
在C#中,layout并不是一个直接用于C#语言本身的关键字或特性。然而,layout在与C#紧密相关的某些上下文中确实有其用途,特别是在涉及用户界面(UI)设计和数据展示时。以下是几个常见的与layout相关的用法场景:…...

【编程概念基础知识】
、编程基础 一、面向对象的三大特性 1、封装: 盒子、零件、按钮 隐藏对象 的内部状态,并且只通过对象的方法来访问数据 想象你有一个小盒子(这个盒子就是一个类),里面装着一些零件(这些零件就是数据&a…...

【React】深入理解 JSX语法
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 深入理解 JSX语法1. JSX 简介2. JSX 的基本语法2.1 基本结构2.2 与普通 JavaScr…...

【Linux】从零开始使用多路转接IO --- 理解EPOLL的 LT水平触发模式 与 ET边缘触发模式
当你偶尔发现语言变得无力时, 不妨安静下来, 让沉默替你发声。 --- 里则林 --- 从零开始认识多路转接 1 EPOLL优缺点2 EPOLL工作模式 1 EPOLL优缺点 poll 的优点(和 select 的缺点对应) 接口使用方便:虽然拆分成了三个函数,…...

QtLua
描述 QtLua 库旨在使用 Lua 脚本语言使 Qt4/Qt5 应用程序可编写脚本。它是 QtScript 模块的替代品。 QtLua 不会为 Qt 生成或使用生成的绑定代码。相反,它提供了有用的 C 包装器类,使 C 和 lua 对象都可以从 lua 和 C 访问。它利用 Qt 元对象系统将 QOb…...

c++-有关计数、双变量累加、半衰、阶乘、变量值互换的基础知识
C是一种非常强大和灵活的编程语言,它包含了许多重要的概念和技巧。在本文中,我们将重点讨论五个主题:计数、双变量累加、半衰、阶乘和变量值的互换。我们将介绍这些概念的定义、用法、题目、答案和解释,以帮助读者更好地理解和运用…...

MyBatis3-获取参数值的方式、查询功能及特殊SQL执行
目录 准备工作 获取参数值的方式(重点) 查询功能 查询一个实体类对象 查询一个list集合 查询单个数据 查询一条数据为map集合 查询多条数据为map集合 特殊SQL执行 模糊查询 批量删除 动态设置表名 添加功能获取自增的主键 准备工作 模块My…...

web——[SUCTF 2019]EasySQL1——堆叠注入
这个题主要是讲述了堆叠注入的用法,来复现一下 什么是堆叠注入 堆叠注入:将多条SQL语句放在一起,并用分号;隔开。 1.查看数据库的名称 查看数据库名称 1;show databases; 发现有名称为ctftraining的数据库 2.对表进行查询 1;show tabl…...

【Ubuntu学习】Ubuntu无法使用vim命令编辑
问题 在VMware首次安装Ubuntu,使用vi指令对文件进行编辑,按i键后无法更改文件内容。 原因 由于Ubuntu中预装的是vim-tiny,平时开发中需要使用vim-full。 解决方案 卸载预装vim sudo apt-get remove vim-common安装vim-full sudo apt-get …...

UniAPP u-popup 禁止背景滑动
增加class .NoScroll {overflow: hidden;position: fixed; }在外层div上增加该class判断条件...

F5全新报告揭示AI时代API安全面临严峻挑战
F5 《2024年应用策略现状报告:API安全》揭示了 API 保护中的漏洞以及对全面安全措施的迫切需求 西雅图,2024年11月11日 – F5(NASDAQ: FFIV)日前发布《2024年应用策略现状报告:API 安全》(以下简称为“报告”),揭示了跨行业API安全面临的严峻现状。该报告强调了企业API保护方面…...