react-问卷星项目(3)
项目实战
React Hooks
缓存,性能优化,提升时间效率,但是不要为了技术而优化,应该是为了业务而进行优化
内置Hooks保证基础功能,灵活配合实现业务功能,抽离公共部分,自定义Hooks或者第三方,即复用代码
React组件公共逻辑的抽离和复用
- 之前是class组件,现在是函数组件
- class组件:Mixing HOC render-props 来复用
- 函数组件:使用Hooks-当前最完美的解决方法,vue3也参考这种实现方式
useState
用普通的js变量无法触发组件的更新,如下代码,方法触发了,但是数值没更新
function App() {let count = 0;function add() {count++;}// 列表页return (<>{/* <List1></List1> */}<div><button onClick={add}>点我增加 {count}</button></div></>);
}
下面的写法能触发更新。导入useState函数,设置初始数字为0,返回的是一个数组。数组的第一个值就是当前count的值,第二个是setCount函数,就是设置新值的函数,注意必须是传入新的值,不能通过count++传入
import React, { useState } from "react";
import "./List1.css";
// import List1 from "./List1";function App() {// let count = 0;const [count, setCount] = useState(0);function add() {// count++;setCount(count + 1);}// 列表页return (<>{/* <List1></List1> */}<div><button onClick={add}>点我增加 {count}</button></div></>);
}export default App;
state
一个组件的独特记忆
- props是父组件传递过来的信息
- state是组件内部的状态信息,不对外
- state变化触发组件更新,重新渲染rerender
- 特点:
- 异步更新,比如将添加数字抽出为组件,并在每一次点击后打印出来,会发现打印出来的数值是点击前的内容,如图所示。
-
// stateDemo组件 import React, { FC, useState } from "react"; const Demo: FC = () => {const [count, setCount] = useState(0);function add() {// count++;// setCount(count + 1);// 上下两个写法一致,都是异步更新setCount((count) => count + 1);console.log(count);}return (<>{/* <List1></List1> */}<div><button onClick={add}>点我增加 {count}</button></div></>); }; export default Demo;
- 如果一个变量不用jsx显示,就不需要用state来管理。比如设置一个变量name,页面上并不需要展示这个变量,但是每次方法的时候会调用setState来设置name,而setState只要改变就会触发页面更新,这就导致不需要的变量触发了页面的更新。这种情况下用useRef
-
- 可能会被合并,state异步更新,相同的内容执行的时候每次传入的都是最新的值,无论多少次被更新都是执行的相同步骤,导致结果应该为5的倍数却还是123这样子增加,用下面函数更新的方式可以解决合并问题
-
// stateDemo组件 import React, { FC, useState } from "react"; const Demo: FC = () => {const [count, setCount] = useState(0);function add() {// count++;// setCount(count + 1); 这个多次执行会导致合并setCount((count) => count + 1);setCount((count) => count + 1);setCount((count) => count + 1);setCount((count) => count + 1);console.log(count);}return (<>{/* <List1></List1> */}<div><button onClick={add}>点我增加 {count}</button></div></>); }; export default Demo;
-
-
不可变数据(重要)
-
不修改state的值,而是传入一个新的值。下列代码中只修改了age,其他属性使用解构语法获得,即解构这个数据对象,未修改的数据保持不变
-
import React, { FC, useState } from "react"; const Demo: FC = () => {const [userInfo, setUserInfo] = useState({ name: "双", age: 20 });// function changeAge() {// setUserInfo({// // 解构语法// ...userInfo,// age: 21,// });// }function addItem() {// 不能使用list.push,因为不可变数据,要传入新值而不是改变state// concat返回的是一个新数组,push返回的不是setList(List.concat("z"));setList([...List, "z"]);}const [List, setList] = useState(["x", "y"]);return (<div><h2>state不可变数据</h2>{/* <div>{JSON.stringify(userInfo)}</div><button onClick={changeAge}></button> */}<div>{JSON.stringify(List)}</div><button onClick={addItem}>add item</button></div>); }; export default Demo;
-
-
实现增删改,因为抽离出了子组件,增删改需要通过父组件触发相应的操作,涉及到一个状态提升的概念,即数据源在父组件中,子组件中只需要执行传递过来的命令,显示数据即可。
-
以下是子组件中的代码,基本思想是面向对象,抽离出一个列表类,因为子组件被抽出所以对子组件进行操作的时候需要通知父组件,自己删除自己不合适
-
// 子组件 uestionCard import React, { FC } from "react"; import "./QuestionCard.css"; type PropsType = {id: string;title: string;isPublished: boolean;// 问号表示这个属性可写可不写,跟flutter语法相似deletQuestion?: (id: string) => void;pubQuestion?: (id: string) => void; };const QuestionCard: FC<PropsType> = (props) => {const { id, title, isPublished, deletQuestion, pubQuestion } = props;function pub(id: string) {pubQuestion && pubQuestion(id);}function del(id: string) {// 与运算符,前一个为true才去执行后一个判断条件deletQuestion && deletQuestion(id);}return (<div key={id} className="list-item"><strong>{title}</strong><br />{/* {条件判断} */}{isPublished ? (<span style={{ color: "green" }}>已发布</span>) : (<span>未发布</span>)}<buttononClick={() => {pub(id);}}>发布问卷</button><buttononClick={() => {del(id);}}>删除问卷</button></div>); };export default QuestionCard;
- 以下是父组件的代码,在父组件中定义对列表元素的增删改后将相应的方法传递给子元素,并在子组件中进行调用
-
import React, { FC, useState } from "react"; import QuestionCard from "./ListCard/QuestionCard"; const List2: FC = () => {const [questionList, setQuestionList] = useState([{ id: "q1", title: "问卷1", isPublished: true },{ id: "q2", title: "问卷2", isPublished: false },{ id: "q3", title: "问卷3", isPublished: false },{ id: "q4", title: "问卷4", isPublished: false },]);// 异步更新所以设置为5const [count, setCount] = useState(5);function deletQuestion(id: string) {// 不可变数据setQuestionList(// 返回true是保存,false就是删除,filter返回的是一个过滤后的新数组questionList.filter((que) => {if (que.id == id) return false;else return true;}),);}function pubQuestion(id: string) {setQuestionList(// 返回的同样是新的数组questionList.map((que) => {if (que.id !== id) return que;return {...que,isPublished: true,};}),);}function add() {setCount((count) => count + 1);setQuestionList(questionList.concat({id: "q" + count,title: "问卷" + count,isPublished: false,}),);}return (<div><h1>问卷列表页2</h1><div>{questionList.map((question) => {const { id, title, isPublished } = question;return (<QuestionCardkey={id}id={id}title={title}isPublished={isPublished}deletQuestion={deletQuestion}pubQuestion={pubQuestion}/>);})}</div><div><button onClick={add}>新增问卷</button></div></div>); }; export default List2;
-
- 异步更新,比如将添加数字抽出为组件,并在每一次点击后打印出来,会发现打印出来的数值是点击前的内容,如图所示。
immer
出现背景,state是不可变数据,并且state操作成本比较高,有很大的不稳定性
- 执行相应的下载指令
npm install immer
- vsc上安装相应的识别插件 Code Spell Checker (可选)
- 以下代码为immer使用,和state做比较
-
// 更换年龄,对象单属性 import React, { FC, useState } from "react"; import { produce } from "immer"; const Demo: FC = () => {const [userInfo, setUserInfo] = useState({ name: "双", age: 20 });function changeAge() {// setUserInfo({// // 解构语法// ...userInfo,// age: 21,// });setUserInfo(produce((item) => {item.age = 21;}),);}return (<div><h2>immer可变数据</h2><div>{JSON.stringify(userInfo)}</div><button onClick={changeAge}>点击更换年龄</button></div>); }; export default Demo;// 更换列表对象的属性 import React, { FC, useState } from "react"; import { produce } from "immer"; const Demo: FC = () => {function addItem() {// 不能使用list.push,因为不可变数据,要传入新值而不是改变state// concat返回的是一个新数组,push返回的不是// setList(List.concat("z"));// setList([...List, "z"]);setList(produce((item) => {item.push("z");}),);}const [List, setList] = useState(["x", "y"]);return (<div><div>{JSON.stringify(List)}</div><button onClick={addItem}>add item</button></div>); }; export default Demo;
-
使用immer重构问卷列表
-
import React, { FC, useState } from "react"; import { produce } from "immer"; import QuestionCard from "./ListCard/QuestionCard"; const List2: FC = () => {const [questionList, setQuestionList] = useState([{ id: "q1", title: "问卷1", isPublished: true },{ id: "q2", title: "问卷2", isPublished: false },{ id: "q3", title: "问卷3", isPublished: false },{ id: "q4", title: "问卷4", isPublished: false },]);// 异步更新所以设置为5const [count, setCount] = useState(5);function deletQuestion(id: string) {// 不可变数据// setQuestionList(// // 返回true是保存,false就是删除,filter返回的是一个过滤后的新数组// questionList.filter((que) => {// if (que.id == id) return false;// else return true;// }),// );// 更换为immer的方法setQuestionList(produce((item) => {// 找到对应的id在列表中的位置const index = item.findIndex((q) => q.id === id);// 在原数组上进行修改使用splice即可item.splice(index, 1);}),);}function pubQuestion(id: string) {// setQuestionList(// // 返回的同样是新的数组// questionList.map((que) => {// if (que.id !== id) return que;// return {// ...que,// isPublished: true,// };// }),// );setQuestionList(produce((item) => {const q = item.find((i) => i.id === id);if (q) q.isPublished = !q.isPublished;}),);}function add() {// setCount((count) => count + 1);// setQuestionList(// questionList.concat({// id: "q" + count,// title: "问卷" + count,// isPublished: false,// }),// );// 替换为immersetCount(produce((item) => {// 这里要返回return不然只增加到5就不递增了,暂不清楚原因return (item += 1);}),);setQuestionList(produce((item) => {item.push({id: "q" + count,title: "问卷" + count,isPublished: false,});}),);}return (<div><h1>问卷列表页2</h1><div>{questionList.map((question) => {const { id, title, isPublished } = question;return (<QuestionCardkey={id}id={id}title={title}isPublished={isPublished}deletQuestion={deletQuestion}pubQuestion={pubQuestion}/>);})}</div><div><button onClick={add}>新增问卷</button></div></div>); }; export default List2;
useEffect
当一个组件渲染完成或者当某个state更新时,加载一个Ajax网络请求,使用useEffect可以实现。state实现不了,因为如果在某个组件中写上需要执行的语句,会导致任何state更新都会触发组件的更新(重新执行函数),不满足初次更新或者某个特定条件更新的两个条件
副作用:本来组件只需要执行完函数即可,但是现在却要求在特定的时间或者满足特定的条件下实现函数,即副作用
数组传入的是依赖项,不设置即为无依赖,即在第一次更新后,后续不会触发,有设置则相应的依赖项改变时会触发这个函数。数组中可以添加多个依赖项,只要其中一个被触发就会执行这个函数
import React, { FC, useState, useEffect } from "react";
import { produce } from "immer";
import QuestionCard from "./ListCard/QuestionCard";
const List2: FC = () => {// 一传函数,二传数组useEffect(() => {console.log("加载Ajax网络请求");}, []);
}
子组件销毁时的调用,能打印出来销毁,但是不知道为什么视频里打印出来单个,但是我打印的时候有其他几个子组件的销毁状态
// QuestionCarduseEffect(() => {console.log("组件挂载");return () => {console.log("组件销毁" + id);};});
解决打印两次的问题。如图所示,为什么会显示打印两次,是因为组件自销毁了一次。从react18开始,useEffect在开发环境下会执行两次,目的是模拟组件创建,销毁,再创建的流程,方便及早发现问题。发布版本就不会有这个问题
通过下列指令发布
npm run build
执行完毕后在build目录下可以查看到项目的相关目录和内容,再通过以下指令运行服务器查看打包后的项目,生产环境下useEffect只执行一次
http-server
npm install -g serve
serve -s build
其他内置Hooks
useRef
- 一般用于操作DOM
import React, { FC, useRef } from "react";
const Demo: FC = () => {// 初始化传入默认值为null,因为初始化的时候页面还没创建// ts泛型const inputRef = useRef<HTMLInputElement>(null);function selectInput() {// 当前指向const inputElm = inputRef.current;if (inputElm) inputElm.select();}return (<div>{/* 通过ref指向DOM节点 */}<input ref={inputRef} defaultValue="hello"></input><button onClick={selectInput}>选中input</button></div>);
};
export default Demo;
- 可传入普通的JS变量,但不会触发rerender(渲染),比如下面这个例子,打印出来的数值改变了,但是界面上展示的数值没有改变,state修改会触发rerender,想要显示出来就用state,只是保存结果就是用ref
const Demo: FC = () => {const nameRef = useRef("双"); // 不是DOM节点而是普通的JS变量function changeName() {nameRef.current = "双月亮";console.log(nameRef.current);}return (<><p>name{nameRef.current}</p><button onClick={changeName}>change name</button></>);
};
- 要和vue3 ref区分开,vue3的ref是用于响应式监听的
useMemo
函数组件,每次state更新都会重新执行函数,useMemo可以缓存数据,不用每次执行函数都重新生成,可用于计算量较大的场景,提高缓存性能
import React, { FC, useMemo, useState } from "react";
const Demo: FC = () => {console.log("demo");const [num1, setNum1] = useState(10);const [num2, setNum2] = useState(20);const [text, setText] = useState("hello");// 跟useEffect相似const sum = useMemo(() => {console.log("gen sum");return num1 + num2;}, [num1, num2]);return (<><p>{sum}</p><div><p>{num1}</p><buttononClick={() => {setNum1(num1 + 1);}}>add num1</button></div><div><p>{num2}</p><buttononClick={() => {setNum2(num2 + 1);}}>add num2</button></div><div>{/* form组件,受控组件 */}<input onChange={(e) => setText(e.target.value)} value={text} /></div></>);
};
export default Demo;
useMemo依赖num1和num2,两个数字变化的时候会触发相应的函数,即重新计算sum,而text不是依赖项,所以text改变的时候不会重新计算sum。
可以把useMemo作为性能优化的手段,但不要把它当成语义上的保证,即不要认为每次使用都会真正的缓存,因为Memo可能会选择性的缓存或者遗忘一个值,然后下次再缓存
useCallback
作用和useMemo一致,也是用于缓存,准们用于缓存函数,可以理解为useMemo的语法糖,下列代码中的两个方法比较类似,fn1是什么时候加载什么时候打印,fn2只有相关依赖改变的时候才会触发
import React, { FC, useState, useCallback } from "react";
const Demo: FC = () => {const [text, setText] = useState("hello");const fn1 = () => console.log("fn1", text);const fn2 = useCallback(() => {console.log("fn2", text);}, [text]);return (<><div><button onClick={fn1}>fn1</button> {" "}<button onClick={fn2}>fn2</button></div>{/* form组件,受控组件,即输入的时候会导致页面数值的变化,类似vue的双向数据绑定 */}<input onChange={(e) => setText(e.target.value)} value={text} /></>);
};
export default Demo;
自定义hooks
抽离出来的这个组件定义为ts组件即可
// ts文件即可,因为没有JSX片段,即div等标签
import { useEffect } from "react";
function useTitle(title: string) {useEffect(() => {document.title = title;}, []);
}
export default useTitle;
监听鼠标事件
import { useState, useEffect } from "react";
// 获取鼠标位置
function useMouse() {const [x, setX] = useState(0);const [y, setY] = useState(0);// "这个组件",即谁引用就指向谁useEffect(() => {const mouseMoveHandler = (event: MouseEvent) => {setX(event.clientX);setY(event.clientY);};// 监听鼠标事件window.addEventListener("mousemove", mouseMoveHandler);// 组件销毁时一定要解绑DOM事件,不然可能会出现内存泄漏问题// 解绑的时候需要和绑定的时候的函数相同return () => {window.removeEventListener("mousemove", mouseMoveHandler);};}, []);return { x, y };
}
export default useMouse;
模拟异步加载数据
import { useState, useEffect } from "react";
function getInfo(): Promise<string> {// 模拟异步信息return new Promise((resolve) => {setTimeout(() => {resolve(Date.now().toString());}, 1500);});
}const useGetInfo = () => {const [loading, setLoading] = useState(true);const [info, setInfo] = useState("");useEffect(() => {getInfo().then((info) => {setLoading(false);setInfo(info);});}, []);return { loading, info };
};
export default useGetInfo;
第三方Hooks
- ahooks国内流行 官网
- react-hooks国外流程
使用下列指令下载ahooks
npm install ahooks --save
下载完后看官网的文档选择调用即可,官网有相关的讲解
使用规则
- 必须用useXxx格式命名
- 只能在两个地方调用Hook(组件内,其他Hook内)
- 必须保证每次调用顺序一致(不能把hooks放在for if内部,只能放在函数第一层,可以在hooks内部加逻辑判断)
闭包陷阱
当异步函数获取state时,可能不是当前最新的state,可使用useRef解决
- 对闭包问题还有点疑惑,通过文心一言描述一下,下面的代码中,
setTimeout
函数在调用时捕获了count
变量的当前值(在其调用时的值)。由于setTimeout
是异步执行的,它在 3 秒后执行时,并不会自动获取count
的最新值。这就是闭包的作用:它保存了函数定义时的环境(在这里是count
的值),
import React, { FC, useState, useEffect, useRef } from "react";
const Demo: FC = () => {const [count, setCount] = useState(0);function add() {setCount(count + 1);}function alertFn() {setTimeout(() => {alert(count);}, 3000);}return (<><p>闭包陷阱</p><div><span>{count}</span><button onClick={add}>add</button><button onClick={alertFn}>alert</button></div></>);
};export default Demo;
上述问题就是当异步函数获取state时,可能不是当前最新的state,接下来使用useRef解决,本质是因为count是一个值类型,而ref是引用类型
import React, { FC, useState, useEffect, useRef } from "react";
const Demo: FC = () => {const [count, setCount] = useState(0);const countRef = useRef(0);useEffect(() => {countRef.current = count;}, [count]);function add() {setCount(count + 1);}function alertFn() {setTimeout(() => {// alert(count);alert(countRef.current);}, 3000);}return (<><p>闭包陷阱</p><div><span>{count}</span><button onClick={add}>add</button><button onClick={alertFn}>alert</button></div></>);
};export default Demo;
相关文章:

react-问卷星项目(3)
项目实战 React Hooks 缓存,性能优化,提升时间效率,但是不要为了技术而优化,应该是为了业务而进行优化 内置Hooks保证基础功能,灵活配合实现业务功能,抽离公共部分,自定义Hooks或者第三方&am…...

69 BERT预训练_by《李沐:动手学深度学习v2》pytorch版
系列文章目录 文章目录 系列文章目录NLP里的迁移学习Bert的动机Bert架构对输入的修改五、预训练任务1、2、3、 六、1、2、3、 七、1、2、3、 八、1、2、3、 NLP里的迁移学习 之前是使用预训练好的模型来抽取词、句子的特征,例如 word2vec 或语言模型这种非深度学习…...

Java报错输出的信息究竟是什么?
Java报错输出的信息究竟是什么? 本篇会带大家了解一下java运行时报错输出的信息内容,简单学习一下虚拟机内存中Java虚拟机栈的工作方式以及栈帧中所存储的信息内容 异常信息 当你的程序运行报错时,你是否会好奇打印出来的那一大坨红色的究竟…...

解表之紫苏
** 声明:本文介绍的中药仅供学习使用,请勿擅自使用,否则后果自负!!!因水平有限,如有不当之处,请批评指正!!!!图片来源网络࿰…...

JavaScript数据类型
目录 JavaScripit数据类型 原始类型(Primitive Types) 1 Undefined 特点 实例 2 Null 实例 3 Boolean 重点: 常用falsy情况: 思考 4 Number,BigInt 实例 特点 NaN 5 String 在JavaScript中表示字符串有三种表示方…...

市场中的新兴力量与未来发展
在当前瞬息万变的全球金融市场中,期货交易以其高杠杆与灵活性,吸引了越来越多的投资者参与其中。大粤期货作为中国期货行业的新兴力量,凭借其创新的交易平台、广泛的产品线及专业的风险管理服务,迅速在市场中崭露头角。本文将介绍…...

Golang | Leetcode Golang题解之第446题等差数列划分II-子序列
题目: 题解: func numberOfArithmeticSlices(nums []int) (ans int) {f : make([]map[int]int, len(nums))for i, x : range nums {f[i] map[int]int{}for j, y : range nums[:i] {d : x - ycnt : f[j][d]ans cntf[i][d] cnt 1}}return }...

Java 常用序列化对比
Java 中常用的序列化方式主要包括以下几种: 1. Java 原生序列化 使用方式: 使用 java.io.Serializable 接口。对象需要实现该接口,然后通过 ObjectOutputStream 和 ObjectInputStream 进行序列化和反序列化。 示例代码: import java.io.*;public class Person impleme…...

【redis学习篇1】redis基本常用命令
目录 redis存储数据的模式 常用基本命令 一、set 二、keys pattern keys 字符串当中携带问号 keys 字符串当中携带*号 keys 【^字母】 keys * 三、exists 四、del 五、expire 5.1 ttl命令 5.2key删除策略 5.2.1惰性删除 5.2.2定期删除 六、type key的数据类型…...

量子计算:颠覆未来计算的革命性技术
量子计算:颠覆未来计算的革命性技术 量子计算作为下一代颠覆性技术,正在引领计算领域的重大变革。与传统计算机基于比特的二进制运算不同,量子计算通过量子比特(qubits)在叠加态和纠缠态下实现并行计算,能…...

ctfshow-web入门(信息收集,持续更新中。。)
写在之前:近期打了个比赛,备受打击,入手了vip账号进修,加油! 文章目录 ctfshow-web1查看源代码ctfshow-web2burp抓包ctfshow-web3burp抓包ctfshow-web4访问robots.txtctfshow-web5dirscarch扫描PHPS文件泄露ctfshow-web6dirscarch扫描ctfshow-web7dirscarch扫描ctfshow-w…...

蓝桥杯【物联网】零基础到国奖之路:十五. 扩展模块之双路ADC
蓝桥杯【物联网】零基础到国奖之路:十五. 扩展模块之双路ADC 第一节 硬件解读第二节 CubeMX配置第三节 代码编写 第一节 硬件解读 STM32的ADC是12位,通过硬件过采样扩展到16位,模数转换器嵌入到STM32L071xx器件中。有16个外部通道和2个内部通道…...

李飞飞谈AI+3D发展:3D/4D AI将成为下一个重要前沿
人工智能(AI)的发展已经深刻改变了我们的世界,从简单的图像识别到复杂的自然语言处理,再到如今正在兴起的生成式模型。在这个过程中,李飞飞教授认为,3D/4D AI技术将是推动下一波变革的关键力量。以下根据她的观点整理了AI发展历程中的关键里程碑以及对3D/4D AI未来发展的…...

centos72009源码编译R语言
./dev/make-distribution.sh --name custom-spark --pip --r --tgz -Pconnect -Psparkr -Phive -Phive-thriftserver -Pmesos -Pyarn -Dhadoop.version3.4.0 -Pkubernetes spark3.5.3 源码版本 ./dev/make-distribution.sh --name custom-spark --pip --r --tgz -Pconnect -P…...

初识算法 · 双指针(4)
目录 前言: 复写零 题目解析 算法原理 算法编写 四数之和 题目解析 算法原理 算法编写 前言: 本文是双指针算法的最后一文,以复写零和四数之和作为结束,介绍方式同样是题目解析,算法原理,算法编写…...

java版鸿鹄电子招投标系统功能架构设计 核心功能设计 鸿鹄电子招投标采购系统源码
java版鸿鹄电子招投标系统功能架构设计 核心功能设计 鸿鹄电子招投标采购系统源码...

matlab 判断多组数据的分布是否一致,可以使用什么方法?
在 MATLAB 中,可以使用以下几种方法来判断多组数据的分布是否一致: 1. Kolmogorov-Smirnov 检验 (K-S Test) K-S 检验是一种非参数检验,用于比较两组数据是否来自相同的分布。MATLAB 提供了 kstest2 函数来进行这种检验。该方法适用于连续分…...

jenkins配置eureka、nacos发布优雅上下线服务
eureka发布期间优雅上下线 1、编写eureka下线脚本 vim biz_out_of_service-eureka.pyimport sys import requests#服务名,脚本第一个参数 APP_NAMEsys.argv[1] # 需要置为OUT_OF_SERVICE的服务实例的ID,脚本第二个参数 INSTANCE_IDsys.argv[2]# Eureka…...

【JAVA开源】基于Vue和SpringBoot的周边产品销售网站
本文项目编号 T 061 ,文末自助获取源码 \color{red}{T061,文末自助获取源码} T061,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…...

【C++差分数组】2381. 字母移位 II|1793
本文涉及知识点 C差分数组 LeetCode2381. 字母移位 II 给你一个小写英文字母组成的字符串 s 和一个二维整数数组 shifts ,其中 shifts[i] [starti, endi, directioni] 。对于每个 i ,将 s 中从下标 starti 到下标 endi (两者都包含&#…...

【pytorch】范数的计算
近日在看沐神的《动手学深度学习》,其中提到了范数这一数学概念,感觉很陌生,参考ChatGPT补一下知识。 目录 范数示例 1: 计算向量的 L2 范数(欧几里得范数)示例 2: 计算矩阵的 Frobenius 范数示例 3: 计算向量的 L1 范数(曼哈顿距离)曼哈顿范数的定义曼哈顿范数的计算示…...

MATLAB|基于多主体主从博弈的区域综合能源系统低碳经济优化调度
目录 主要内容 程序亮点: 模型研究 一、综合能源模型 二、主从博弈框架 部分代码 结果一览 下载链接 主要内容 程序参考文献《基于多主体主从博弈的区域综合能源系统低碳经济优化调度》,采用了区域综合能源系统多主体博弈协同优化方…...

Django 后端数据传给前端
Step 1 创建一个数据库 Step 2 在Django中点击数据库连接 Step 3 连接成功 Step 4 settings中找DATABASES Step 5 将数据库挂上面 将数据库引擎和数据库名改成自己的 Step 6 在_init_.py中加上数据库的支持语句 import pymysql pymysql.install_as_MySQLdb() Step7 简单创建两…...

elasticsearch 写入新数据测试(二)
背景:elasticsearch单个node节点写入数据-CSDN博客 需要设置密码才能作为外部调用,不设置我不会用。设置方法见上一篇。 设置密码出现如下问题: Unexpected response code [503] from calling PUT http://172.19.0.1:9200/_security/user/apm_system/_password?pretty …...

android navigation 用法详细使用
Navigation 的关键概念 1、Navigation Graph: 定义了应用内的所有导航目的地以及它们之间的连接。 2、NavHost: 一个 UI 元素,用于承载当前的导航目的地。 3、NavController: 管理目的地之间的导航。 4、Destination: 导航图中的一个节点,用户导航到该节…...

uni-app在线预览pdf
这里推荐下载pdf.js 插件 PDF.js - Browse Files at SourceForge.net 特此注意 如果报 Promise.withResolvers is not a function 请去查看版本兼容问题 降低pdf.js版本提高node版本 下载完成后 在 static 文件夹下新建 pdf 文件夹,将解压文件放进 pdf 文件…...

SpringBoot--为什么Controller是串行的?怎样才能并行?
原文网址:SpringBoot--为什么Controller是串行的?怎样才能并行?-CSDN博客 简介 本文介绍SpringBoot为什么Controller是串行的?在什么场景下才能并行执行? 大家都知道,SpringBoot的Controller按理是并行执…...

C/C++ 中的未定义行为(Undefined Behavior, UB)
0. 简介 在 C/C 编程中,理解未定义行为(UB)及其相关概念至关重要。本文将对未定义行为进行详细解析,并通过实例展示其影响与处理方法。 1. 概念辨析 在 C/C 中,未定义行为容易与以下两个概念混淆: 1.1 …...

AJAX 1——axios体验、认识URL、常用请求方法、HTTP协议、错误处理、form-serialize插件
AJAX 1——axios体验、认识URL、常用请求方法、HTTP协议、错误处理、form-serialize插件 1.AJAX入门与体验axios 定义:浏览器与服务器进行数据通信的技术 体验axios库,与服务器通信 引入axios.js使用axios函数 <p class"my-p"></p&…...

Java-运算符
一、运算符是什么? 其实就如字面意思一样啦~就像数学中的运算符一样:(" "," - "," * "," / "," % "...)。 计算机的用途就如其名:运算。而既然要运算…...