怎样做企业网站建设/网站建设的好公司
React学习【二】
- 2 添加交互
- 2.1 响应事件
- 2.1.1 添加事件处理函数
- 2.1.2 在事件处理函数中读取`props`
- 2.1.3 将事件处理函数作为`props`传递
- 2.1.4 命名事件处理函数prop
- 2.1.5 事件传播
- 2.1.6 阻止传播
- 2.1.7 传递处理函数作为事件传播的替代方案
- 2.1.8 阻止默认行为
- 2.2 State: 组件的记忆
- 2.2.1 添加一个state变量
- 2.2.2 Hook函数
- 2.2.3 剖析useState
- 2.2.3 赋予一个组件多个state变量
- 2.2.4 State是隔离且私有的
- 2.3 渲染和提交
- 2.4 state在渲染时不会发生更改
- 2.5 把一系列state更新加入队列
- 2.5.1 React会对state更新进行批处理
- 2.5.2 在下次渲染前多次更新同一个state
- 2.5.3 state更新函数的命名惯例
- 2.6 更新state中的对象
- 2.6.1 使用展开语法复制对象
- 2.6.2 使用一个事件处理函数来更新多个字段
- 2.6.3 更新一个嵌套的对象
- 2.6.4 使用Immer编写更简洁的更新逻辑
- 2.7 更新State中的数组
- 2.7.1 更新数组内部的对象
2 添加交互
在 React 中,随时间变化的数据被称为状态(state
)。
2.1 响应事件
事件处理程序是开发者自己写的的函数,它将在用户交互时被触发,如点击、悬停、焦点在表单输入框上等等。
<button>
等内置组件只支持内置浏览器事件,如 onClick
。但是,开发者也可以创建自己的组件,并给它们的事件处理程序 props
指定名称。
2.1.1 添加事件处理函数
如果需要添加一个事件处理函数,需要先定义一个函数,然后将其作为prop
传入合适的JSX标签.
事件处理函数有如下特点:
- 通常在组件内部定义
- 名称以
handle
开头,后跟事件名称
当函数体较短时,内联事件处理函数会很方便。比如:
<button onClick={function handleClick() {alert('你点击了我!');
}}>// 箭头函数
<button onClick={() => {alert('你点击了我!');
}}>
传递给事件处理函数的函数应直接传递<button onClick={handleClick}>
,而非调用<button onClick={handleClick()}>
。加上()
后函数会立即执行,而不是点击按钮时才执行。传递内联函数时,应该将内联事件处理函数包装在匿名函数中。
2.1.2 在事件处理函数中读取props
由于事件处理函数声明于组件内部,因此它们可以直接访问组件的 props。
2.1.3 将事件处理函数作为props
传递
将组件从父组件接收的 prop 作为事件处理函数传递。
function Button({ onClick, children }) {return (<button onClick={onClick}>{children}</button>);
}function PlayButton({ movieName }) {function handlePlayClick() {alert(`正在播放 ${movieName}!`);}return (<Button onClick={handlePlayClick}>播放 "{movieName}"</Button>);
}function UploadButton() {return (<Button onClick={() => alert('正在上传!')}>上传图片</Button>);
}export default function Toolbar() {return (<div><PlayButton movieName="魔女宅急便" /><UploadButton /></div>);
}
2.1.4 命名事件处理函数prop
- 按照惯例,事件处理函数 props 应该以
on
开头,后跟一个大写字母。 - 确保为事件处理程序使用适当的
HTML
标签。
2.1.5 事件传播
如果子组件定义了一个函数,那么在子组件函数被触发后,会向上冒泡到父级组件层级。
在 React 中所有事件都会传播,除了
onScroll
,它仅适用于你附加到的 JSX 标签。
2.1.6 阻止传播
事件处理函数接收一个 事件对象 作为唯一的参数。按照惯例,它通常被称为 e
,代表 “event”(事件)。这个事件对象还允许阻止传播。如果想阻止一个事件到达父组件,需要调用 e.stopPropagation()
。
function Button({ onClick, children }) {return (<button onClick={e => {e.stopPropagation();onClick();}}>{children}</button>);
}export default function Toolbar() {return (<div className="Toolbar" onClick={() => {alert('你点击了 toolbar !');}}><Button onClick={() => alert('正在播放!')}>播放电影</Button><Button onClick={() => alert('正在上传!')}>上传图片</Button></div>);
}
当点击按钮时:
- React 调用了传递给
<button>
的onClick
处理函数。 - 定义在Button中的处理函数执行了如下操作:
- 调用
e.stopPropagation()
,阻止事件进一步冒泡。 - 调用
onClick
函数,它是从Toolbar
组件传递过来的 prop。
- 调用
- 在
Toolbar
组件中定义的函数,显示按钮对应的 alert。 - 由于传播被阻止,父级
<div>
的onClick
处理函数不会执行。
若想对每次点击进行埋点记录,可以通过在事件名称末尾添加
Capture
来实现。<div onClickCapture={() => { /* 这会首先执行 */ }}><button onClick={e => e.stopPropagation()} /><button onClick={e => e.stopPropagation()} /> </div>
每个事件分三个阶段传播:
- 它向下传播,调用所有的
onClickCapture
处理函数。- 它执行被点击元素的
onClick
处理函数。- 它向上传播,调用所有的
onClick
处理函数。捕获事件对于路由或数据分析之类的代码很有用。
2.1.7 传递处理函数作为事件传播的替代方案
此处的点击事件处理函数先执行了一行代码,然后调用了父组件传递的 onClick
prop:
function Button({ onClick, children }) {return (<button onClick={e => {e.stopPropagation();onClick();}}>{children}</button>);
}
也可以在调用父元素 onClick
函数之前,向这个处理函数添加更多代码。
2.1.8 阻止默认行为
某些浏览器事件具有与事件相关联的默认行为。例如,点击 <form>
表单内部的按钮会触发表单提交事件,默认情况下将重新加载整个页面:
export default function Signup() {return (<form onSubmit={() => alert('提交表单!')}><input /><button>发送</button></form>);
}
可以调用事件对象中的 e.preventDefault()
来阻止这种情况。
export default function SignUp() {return (<form onSubmit={e => {e.preventDefault();alert('提交表单!');}}><input /><button>发送</button></form>);
}
e.stopPropagation()
阻止触发绑定在外层标签上的事件处理函数。e.preventDefault()
阻止少数事件的默认浏览器行为。
2.2 State: 组件的记忆
要使用新数据更新组件,需要做两件事:
- 保留 渲染之间的数据。
- 触发 React 使用新数据渲染组件(重新渲染)。
useState
Hook 提供了这两个功能:
- State 变量 用于保存渲染间的数据。
- State setter 函数 更新变量并触发 React 再次渲染组件。
2.2.1 添加一个state变量
import { useState } from 'react'const [index, setIndex] = useState[0];function handleClick() {setIndex(index + 1);
}
2.2.2 Hook函数
在 React 中,useState
以及任何其他以“use
”开头的函数都被称为 Hook。
Hooks ——以
use
开头的函数——只能在组件或自定义 Hook 的最顶层调用。 你不能在条件语句、循环语句或其他嵌套函数内调用 Hook。Hook 是函数,但将它们视为关于组件需求的无条件声明会很有帮助。在组件顶部 “use” React 特性,类似于在文件顶部“导入”模块。
2.2.3 剖析useState
注意:惯例是将这对返回值命名为
const [thing, setThing]
。
useState
的唯一参数是 state 变量的初始值。
每次你的组件渲染时,useState
都会给你一个包含两个值的数组:
- state 变量 (
index
) 会保存上次渲染的值。 - state setter 函数 (
setIndex
) 可以更新 state 变量并触发 React 重新渲染组件。
2.2.3 赋予一个组件多个state变量
可以在一个组件中拥有任意多种类型的 state
变量。
useState
的实现依靠的是数组:在 React 内部,为每个组件保存了一个数组,其中每一项都是一个
state
对。它维护当前state
对的索引值,在渲染之前将其设置为 “0
”。每次调用useState
时,React 都会为你提供一个state
对并增加索引值。
2.2.4 State是隔离且私有的
如果你渲染同一个组件两次,每个副本都会有完全隔离的 state
!改变其中一个不会影响另一个。
与 props
不同,state
完全私有于声明它的组件。
State 变量仅用于在组件重渲染时保存信息。在单个事件处理函数中,普通变量就足够了。当普通变量运行良好时,不要引入 state 变量。比如:
export default function FeedbackForm() {function handleClick() {const name = prompt('What is your name?');alert(`Hello, ${name}!`);}return (<button onClick={handleClick}>Greet</button>);
}
2.3 渲染和提交
React请求和提供UI的过程总共包括三个步骤:
- 触发渲染
- 组件的 初次渲染。
- 组件(或者其祖先之一)的 状态发生了改变。
- 渲染组件
- 在进行初次渲染时, React 会调用根组件
root
。 - 对于后续的渲染, React 会调用那些使内部状态更新从而触发渲染的函数组件。
- 在进行初次渲染时, React 会调用根组件
- 提交到DOM
- 对于初次渲染, React 会使用
appendChild()
DOM API 将其创建的所有 DOM 节点放在屏幕上。 - 对于重复渲染, React 将只执行必要渲染操作,以使得 DOM节点 与最新的渲染输出结果匹配一致。
- 对于初次渲染, React 会使用
2.4 state在渲染时不会发生更改
一个 state 变量的值永远不会在一次渲染的内部发生变化, 即使其事件处理函数的代码是异步的。
2.5 把一系列state更新加入队列
2.5.1 React会对state更新进行批处理
React 会等到事件处理函数中的 所有 代码都运行完毕再处理你的 state 更新。
比如
setNumber(0 + 1);
setNumber(0 + 1);
setNumber(0 + 1);
组件的重新渲染只会发生在这三次setNumber()
调用之后。
2.5.2 在下次渲染前多次更新同一个state
若多次更新同一个state
,React
会将每一次state
的更新状态存入队列,并把最后的结果更新到state
中。这称为批处理。
以下是可以考虑传递给 setNumber
state 设置函数的内容:
- 一个更新函数(例如:
n => n + 1
)会被添加到队列中。 - 任何其他的值(例如:数字
5
)会导致“替换为5
”被添加到队列中,已经在队列中的内容会被忽略。
2.5.3 state更新函数的命名惯例
通常可以通过相应 state 变量的第一个字母来命名更新函数的参数,也可以用更明晰的命名:
setEnabled(e => !e);
setLastName(ln => ln.reverse());
setFriendCount(fc => fc * 2);
2.6 更新state中的对象
应该 把所有存放在 state 中的 JavaScript 对象都视为只读的。在改变state时,不能改变state中现有的对象,要重新创建一个对象把原来的对象替换掉。比如下面两种写法是正确且等价的:
// 第一种
const nextPosition = {};
nextPosition.x = e.clientX;
nextPosition.y = e.clientY;
setPosition(nextPosition);// 第二种
setPosition({x: e.clientX,y: e.clientY
});
2.6.1 使用展开语法复制对象
通常,你会希望把 现有 数据作为你所创建的新对象的一部分。例如,你可能只想要更新表单中的一个字段,其他的字段仍然使用之前的值。那么此时就可以用展开语法...
import { useState } from 'react';export default function Form() {const [person, setPerson] = useState({firstName: 'Barbara',lastName: 'Hepworth',email: 'bhepworth@sculpture.com'});function handleFirstNameChange(e) {setPerson({...person,firstName: e.target.value});}function handleLastNameChange(e) {setPerson({...person,lastName: e.target.value});}function handleEmailChange(e) {setPerson({...person,email: e.target.value});}return (<><label>First name:<inputvalue={person.firstName}onChange={handleFirstNameChange}/></label><label>Last name:<inputvalue={person.lastName}onChange={handleLastNameChange}/></label><label>Email:<inputvalue={person.email}onChange={handleEmailChange}/></label><p>{person.firstName}{' '}{person.lastName}{' '}({person.email})</p></>);
}
请注意 ...
展开语法本质是是“浅拷贝”——它只会复制一层。这使得它的执行速度很快,但是也意味着当你想要更新一个嵌套属性时,你必须得多次使用展开语法。
2.6.2 使用一个事件处理函数来更新多个字段
import { useState } from 'react';export default function Form() {const [person, setPerson] = useState({firstName: 'Barbara',lastName: 'Hepworth',email: 'bhepworth@sculpture.com'});function handleChange(e) {setPerson({...person,[e.target.name]: e.target.value // 重点是这里,使用 DOM 元素的 name属性});}return (<><label>First name:<inputname="firstName"value={person.firstName}onChange={handleChange}/></label><label>Last name:<inputname="lastName"value={person.lastName}onChange={handleChange}/></label><label>Email:<inputname="email"value={person.email}onChange={handleChange}/></label><p>{person.firstName}{' '}{person.lastName}{' '}({person.email})</p></>);
}
在这里,e.target.name
引用了 <input>
这个 DOM 元素的 name
属性。
2.6.3 更新一个嵌套的对象
如果对象拥有多层嵌套,那么可以创建新的对象:
const nextArtwork = { ...person.artwork, city: 'New Delhi' };
const nextPerson = { ...person, artwork: nextArtwork };
setPerson(nextPerson);
或者写成一个函数调用:
setPerson({...person, // 复制其它字段的数据 artwork: { // 替换 artwork 字段 ...person.artwork, // 复制之前 person.artwork 中的数据city: e.target.value // 但是将 city 的值替换为 New Delhi!}
});
对象并非真正嵌套,只是属性"指向"彼此而已。
2.6.4 使用Immer编写更简洁的更新逻辑
由
Immer
提供的draft
是一种特殊类型的对象,被称为 Proxy,它会记录你用它所进行的操作。从原理上说,Immer
会弄清楚draft
对象的哪些部分被改变了,并会依照你的修改创建出一个全新的对象。
使用Immer
:
- 运行
npm install use-immer
添加Immer
依赖 - 用
import { useImmer } from 'use-immer'
替换掉import { useState } from 'react'
import { useImmer } from 'use-immer';export default function Form() {const [person, updatePerson] = useImmer({name: 'Niki de Saint Phalle',artwork: {title: 'Blue Nana',city: 'Hamburg',image: 'https://i.imgur.com/Sd1AgUOm.jpg',}});function handleNameChange(e) {updatePerson(draft => {draft.name = e.target.value;});}function handleTitleChange(e) {updatePerson(draft => {draft.artwork.title = e.target.value;});}function handleCityChange(e) {updatePerson(draft => {draft.artwork.city = e.target.value;});}function handleImageChange(e) {updatePerson(draft => {draft.artwork.image = e.target.value;});}return (<><label>Name:<inputvalue={person.name}onChange={handleNameChange}/></label><label>Title:<inputvalue={person.artwork.title}onChange={handleTitleChange}/></label><label>City:<inputvalue={person.artwork.city}onChange={handleCityChange}/></label><label>Image:<inputvalue={person.artwork.image}onChange={handleImageChange}/></label><p><i>{person.artwork.title}</i>{' by '}{person.name}<br />(located in {person.artwork.city})</p><img src={person.artwork.image} alt={person.artwork.title}/></>);
}
为什么在 React 中不推荐直接修改 state?
- 调试时使用
console.log()
可以很容易发现前后两次渲染发生了什么变化.- React常见的优化策略依赖于如果之前的
props
或者state
的值和下一次相同就跳过渲染。- 如果用户需求变更,可以很容易恢复到以前的版本。
2.7 更新State中的数组
同对象一样,当想要更新存储于 state
中的数组时,需要创建一个新的数组(或者创建一份已有数组的拷贝值),并使用新数组设置 state
。
当操作 React state 中的数组时,需要避免使用左列能改变原数组的方法,而首选右列能返回一个新数组的方法:
避免使用(会改变原始数组) | 推荐使用(返回一个新数组) | |
---|---|---|
添加元素 | push /unshift | concat /[...arr] 展开语法 |
删除元素 | pop /shift /splice | filter /slice |
替换元素 | splice /arr[i]=...赋值 | map |
排序 | reverse /sort | 先将数组复制一份、toSorted |
或者使用Immer
。
2.7.1 更新数组内部的对象
即使拷贝了数组,还是不能直接修改其内部的元素。这是因为数组的拷贝是浅拷贝——新的数组中依然保留了与原始数组相同的元素。
比如这样就不行:
const nextList = [...list];
nextList[0].seen = true; // 问题:直接修改了 list[0] 的值
setList(nextList);
正确的做法是再次拷贝一份,然后进行修改,我们可以使用map
函数:
setMyList(myList.map(artwork => {if (artwork.id === artworkId) {// 创建包含变更的*新*对象return { ...artwork, seen: nextSeen };} else {// 没有变更return artwork;}
}));
或者使用更简洁的immer
:
updateMyTodos(draft => {const artwork = draft.find(a => a.id === artworkId);artwork.seen = nextSeen;
});
增
最简单的一种就是使用 ...
数组展开 语法:
setArtists( // 替换 state[ // 是通过传入一个新数组实现的...artists, // 新数组包含原数组的所有元素{ id: nextId++, name: name } // 并在末尾添加了一个新的元素]
);
数组展开运算符还允许你把新添加的元素放在原始的 ...artists
之前:
setArtists([{ id: nextId++, name: name },...artists // 将原数组中的元素放在末尾
]);
这样一来,展开操作就可以完成 push()
和 unshift()
的工作,将新元素添加到数组的末尾和开头.
删
从数组中删除一个元素最简单的方法就是将它过滤出去。可以通过 filter
方法实现:
// 使用filter方法删除元素
setArtists(artists.filter(a =>a.id !== artist.id)
);
改
如果想改变数组中的某些或全部元素,可以先用 map()
创建一个新数组。再使用新的数组进行重新渲染。
import { useState } from 'react';let initialShapes = [{ id: 0, type: 'circle', x: 50, y: 100 },{ id: 1, type: 'square', x: 150, y: 100 },{ id: 2, type: 'circle', x: 250, y: 100 },
];export default function ShapeEditor() {const [shapes, setShapes] = useState(initialShapes);function handleClick() {const nextShapes = shapes.map(shape => {if (shape.type === 'square') {// 不作改变return shape;} else {// 返回一个新的圆形,位置在下方 50px 处return {...shape,y: shape.y + 50,};}});// 使用新的数组进行重渲染setShapes(nextShapes);}return (<><button onClick={handleClick}>所有圆形向下移动!</button>{shapes.map(shape => (<divkey={shape.id}style={{background: 'purple',position: 'absolute',left: shape.x,top: shape.y,borderRadius:shape.type === 'circle'? '50%' : '',width: 20,height: 20,}} />))}</>);
}
插入元素
向数组特定位置插入一个元素。可以将数组展开运算符 ...
和 slice()
方法一起使用。
function handleClick() {const insertAt = 1; // 可能是任何索引const nextArtists = [// 插入点之前的元素:...artists.slice(0, insertAt),// 新的元素:{ id: nextId++, name: name },// 插入点之后的元素:...artists.slice(insertAt)];setArtists(nextArtists);setName('');}
其他改变数组中元素的情况,可以先拷贝这个数组,再改变这个拷贝后的值。
相关文章:

【React】React学习:从初级到高级(二)
React学习【二】 2 添加交互2.1 响应事件2.1.1 添加事件处理函数2.1.2 在事件处理函数中读取props2.1.3 将事件处理函数作为props传递2.1.4 命名事件处理函数prop2.1.5 事件传播2.1.6 阻止传播2.1.7 传递处理函数作为事件传播的替代方案2.1.8 阻止默认行为 2.2 State: 组件的记…...

无法将类型为“Newtonsoft.Json.Linq.JObject”的对象转换为类型“Newtonsoft.Json.Linq.JArray”解决方法
对于“Newtonsoft.Json.Linq.JObject”的对象强制类型转换为类型“Newtonsoft.Json.Linq.JArray”报错 第一的图为对象{“*************”:“********”} 第二个图片为数组[{“…”:“…”}] 在我这里进行强制转换对象转换为类型“Newtonsoft.Json.Linq.JArray”报错. 那我们…...

从零开始,无需公网IP,搭建本地电脑上的个人博客网站并发布到公网
文章目录 前言1. 安装套件软件2. 创建网页运行环境 指定网页输出的端口号3. 让WordPress在所需环境中安装并运行 生成网页4. “装修”个人网站5. 将位于本地电脑上的网页发布到公共互联网上 前言 在现代社会,网络已经成为我们生活离不开的必需品,而纷繁…...

Excel VSTO开发6 -Range对象
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 6 Range对象 Excel中最重要的一个对象是Range对象,它可以代表某一单元格、某一行、某一列、某一区域(该区域…...

LeetCode 15 三数之和
题目链接 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题目解析 // 1. 排序双指针 // 2. 固定一个值nums[i] 然后去剩下的位置去找 两数之和符合nums[j]nums[k]是否等于-nums[i] // 3. 细节问题:由于题目中是不可以包含重复的三元组的…...

车船边缘网关是如何给车辆船只定位的?
随着智能交通系统的不断发展,车路协同成为了重要的研究方向之一。而AI边缘计算网关在这个领域中发挥着至关重要的作用。本文将重点介绍AI边缘计算网关在车路协同中的应用,并强调其中的重点词汇或短语。 首先,什么是AI边缘计算网关࿱…...

详解MAC帧、ARP、DNS、ICMP协议
局域网通信原理 比如新建了一个内网,如果一台机器A找机器B,封FRAME时(OSI的第二层用的数据格式),要封装对方的MAC,开始时A不知道B的MAC,只知道IP,它就发一个ARP包,源IP是…...

Leetcode:【169. 多数元素】
题目 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 难度:简单 题目链接:169. 多数元素 示例 1ÿ…...

好用免费的Chat GPT
MindLink麦灵 你问我答 灵感 持续更新中。。。。...

MySQL-MHA
目录 1、什么是 MHA 2、MHA 的组成 3、MHA 的特点 3.1 MHA工作原理总结如下 4、搭建 MySQL MHA 4.1 实验环境配置 MHA架构 故障模拟 4.2 安装MHA所有组件 4.3 故障模拟 4.4 总结 1、什么是 MHA MHA(MasterHigh Availability)是一套优秀的My…...

初识Node.js与内置模块
1. 初识 Node.js 1.1 回顾与思考 1. 已经掌握了哪些技术 2. 浏览器中的 JavaScript 的组成部分 3. 思考:为什么 JavaScript 可以在浏览器中被执行 4. 思考:为什么 JavaScript 可以操作 DOM 和 BOM 5. 浏览器中的 JavaScript 运行环境 6. 思考ÿ…...

NLP(1)--NLP基础与自注意力机制
目录 一、词向量 1、概述 2、向量表示 二、词向量离散表示 1、one-hot 2、Bag of words 3、TF-IDF表示 4、Bi-gram和N-gram 三、词向量分布式表示 1、Skip-Gram表示 2、CBOW表示 四、RNN 五、Seq2Seq 六、自注意力机制 1、注意力机制和自注意力机制 2、单个输出…...

Ubuntu 升级cuda版本与切换
下载cuda版本 进:CUDA Toolkit 12.2 Downloads | NVIDIA Developer wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.runsudo sh ./cuda_12.2.0_535.54.03_linux.run --toolkit --silent --overrid…...

精讲算法的时间复杂度
目录 一、算法效率 1.算法效率 1.1如何衡量一个算法的好坏 1.2算法的复杂度 二、时间复杂度 1.时间复杂度的概念 2.大O的渐进表示法 3.常见时间复杂度的计算举例 三、空间复杂度 一、算法效率 1.算法效率 1.1如何衡量一个算法的好坏 long long Fib(int N) {if(N <…...

java八股文面试[多线程]——newWorkStealingPool
newWorkStealingPool是什么? newWorkStealingPool简单翻译是任务窃取线程池。 newWorkStealingPool 是Java8添加的线程池。和别的4种不同,它用的是ForkJoinPool。 使用ForkJoinPool的好处是,把1个任务拆分成多个“小任务”,把这…...

STM32--RTC实时时钟
文章目录 Unix时间戳时间戳转换BKPRTC简介RTC框图硬件电路RTC的注意事项RTC时钟实验工程 Unix时间戳 Unix 时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。 时间戳存储在一个秒计数器中,秒计数器为32位/64…...

【N2】例题学习笔记
N2例题 《新"日本语能力测试"例题集》 听力原稿(PDF) 【10】 【問い】この筆者から見た「仕事ができる人」の特徴はどんなことか。 【提问】这位作者认为,仕事能力强的人具有什么特点呢? 【11】 文章 下の文章は、企業のあり方について…...

【数据分享】2006-2021年我国城市级别的道路、桥梁、管线建设相关指标(10多项指标)
《中国城市建设统计年鉴》中细致地统计了我国城市市政公用设施建设与发展情况,在之前的文章中,我们分享过基于2006-2021年《中国城市建设统计年鉴》整理的2006—2021年我国城市级别的市政设施水平相关指标、2006-2021年我国城市级别的各类建设用地面积数…...

视觉SLAM14讲笔记-第7讲-视觉里程计2
直接法的引出 直接法是视觉里程计另一个主要分支,它与特征点法有很大的不同。 使用特征点法估计相机运动时,我们把特征点看作固定在三维空间的不动点。根据它们在相机中的投影位置,通过最小化重投影误差来优化相机运动。 相对地,…...

MySQL——单行函数和分组函数
2023.9.3 单行函数的SQL语句学习笔记如下: #常见单行函数介绍(部分省略) #字符函数 #将姓变大写,名变小写,然后拼接。 SELECT CONCAT(UPPER(last_name), ,LOWER(first_name)) AS 姓名 FROM employees; # 姓名中首字符…...

百度百科词条怎么更新?怎么能顺利更新百科词条?
企业和个人百度百科词条的更新对于他们来说都具有重要的意义,具体如下: 对企业来说: 塑造品牌形象:百度百科是一个常被用户信任并参考的知识平台,通过更新企业词条可以提供准确、全面的企业信息,帮助企业塑…...

PPT怎么转换为PDF格式,收藏这两个在线工具。
PPT是一种常用的演示文稿格式,它可以包含丰富的动画效果和超链接,让你的内容更加生动和有趣。但是,如果你想将PPT分享给别人,或者在不同的设备上查看,你可能会遇到一些问题,比如: PPT文件太大&a…...

八大排序算法----堆排序
堆排序的基本步骤:(以从大到小的顺序排序为例) 1.构建大顶堆(每个结点的值都大于或等于其左右孩子结点的值) 2.排序:每次堆顶的元素取出来(整个堆中值最大),与最后一个…...

Docker Desktop 设置镜像环境变量
点击run 展开Optional settings container name :容器名称 Ports:根据你需要的端口进行输入,不输入则默认 后面这个 比如我这个 5432 Volumes:卷,也就是做持久化 需要docker 数据保存的地方 Environment variables…...

springboot之一:配置文件(内外部配置优先顺序+properties、xml、yaml基础语法+profile动态切换配置、激活方式)
配置的概念: Spring Boot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。 注意配置文件的命名必须是applicat…...

涛然自得周刊(第 5 期):蝲蛄吟唱的地方
作者:何一涛 日期:2023 年 8 月 20 日 涛然自得周刊主要精选作者阅读过的书影音内容,不定期发。历史周刊内容可以看这里。 电影 《沼泽深处的女孩》 改编自小说《蝲蛄吟唱的地方》,主角是一位在沼泽地独自生活并长大的女孩&…...

Android Ble蓝牙App(七)扫描过滤
Ble蓝牙App(七)扫描过滤 前言目录正文一、增加菜单二、使用MMKV① 添加依赖② 封装MMKV③ 使用MMKV 三、过滤空设备名四、过滤Mac地址五、过滤RSSI六、源码 前言 在上一篇文章中了解了MTU的相关知识以及对于设备操作信息的展示,本篇文章中将增…...

小程序当前页面栈以及跳转
1.调用页面栈刷新接口 let pages getCurrentPages(); //当前页面栈 if (pages.length > 1) { let beforePage pages[pages.length - 2]; //获取上一个页面实例对象 beforePage.$vm.getActivityLi…...

jQuery获取表单的值val()
(1)页面中有很多元素,包括表单中的输入项,如输入文本框等;获取、设置、输入文本框的值;val()方法。 (2)也包括<p>、<span>等元素;获取、设置这些元素的文本…...

【专栏必读】数字图像处理(MATLAB+Python)专栏目录导航及学习说明
文章目录 第一章:绪论第二章:数字图像处理基础第三章:图像基本运算第四章:图像的正交变换第五章:图像增强第六章:图像平滑第七章:图像锐化第八章:图像复原第九章:图像形态…...