React保姆级教学
React保姆级教学
- 一、创建第一个react项目
- 二、JSX基本语法与react基础知识
- 1、 插值语法:
- 2、 循环一个简单列表
- 3、 实现简单条件渲染
- 4、 实现复杂的条件渲染
- 5、 事件绑定
- 6、 基础组件(函数组件)
- 7、 使用useState
- 8、 基础样式控制
- 9、 动态类名
- 10、 操作表单,实现表单受控绑定。
- 11、 获取DOM
- 12、 好用的第三方库,
- 三、组件通信
- 1、 父传子
- 2、 子传父
- 3、 借助`“状态提升”`机制实现兄弟组件通信
- 4、 使用context机制跨层传递数据
- 四、常用钩子函数介绍
- 4、自定义Hook函数
- 封装通用Hook函数的通用思路
- 5.React Hook函数的使用规则
- 五、Redux快速上手
- 1. 环境搭建
- 2. store目录结构设计
- 3. 使用流程
- 六、ReactRouter快速上手
- 1. 基本使用
- 2. 导航方式
- 3. 路由传参
- 4. 嵌套路由
- 5.默认二级路由
- 6.配置未找到路由的默认展示页面,既404页面
- 7.两种路由模式
- 七、两个联想提示配置
- 八、json-server 构建测试服务
一、创建第一个react项目
- 首先全局安装create-react-app
npm install -g create-react-app
- 安装好后,创建第一个react项目,注意项目名称要小写,并且不能有中文
npx create-react-app my-app
- npx Node.js工具命令,查找并执行后续的包命令
- create-react-app 核心包(固定写法),用于创建React项目
- my-app React项目的名称(可以自定义)
- 创建好后,cd到项目目录下面,执行npm start即可
cd my-app
npm start
二、JSX基本语法与react基础知识
1、 插值语法:
JSX可以通过大括号语法{},识别JS表达式,比如变量,函数调用,方法调用等
,但是只有表达式才可以。if else等语句是不可以的
// 项目的根组件function func() {return '调用了函数'
}
const count = 10function App() {return (<div className="App">{/* 使用引号传递字符串 */}{'this is App'}<br />{/* 使用js变量 */}{count}<br />{/* 调用函数 */}{func()}<br />{/* 方法的调用 */}{new Date().getDate()}<br />{/* 使用js对象 */}<div style={{ color: 'red' }}>使用了js对象</div></div>);
}export default App;
2、 循环一个简单列表
使用的核心方法是map
// 项目的根组件
const list = [{ id: '1001', name: 'Vue' },{ id: '1002', name: 'React' },{ id: '1003', name: 'Angular' },
]
function App() {return (<div className="App"><ul>{list.map(item => <li key={item.id}>{item.name}</li>)}</ul></div>);
}export default App;
3、 实现简单条件渲染
两种方法:使用逻辑与运算符 &&
或者使用三元运算符
// 项目的根组件const isLogin = truefunction App() {return (<div className="App">{/* 逻辑与运算符 && */}{isLogin && <span>已经登录了</span>}<br />{/* 三元运算符 */}{isLogin ? <span>已经登录了</span> : <span>用户未登录</span>}</div>);
}export default App;
4、 实现复杂的条件渲染
通过使用自定义函数和if语句进行渲染
// 项目的根组件const type = 1 // 0 1 3function changeType() {if (type === 0) {return <div>我是第一种情况</div>} else if (type === 1) {return <div>我是第二种情况</div>} else {return <div>我是第三种情况</div>}
}function App() {return (<div>{/* 通过调用函数实现条件渲染 */}{changeType()}</div>);
}export default App;
5、 事件绑定
// 项目的根组件// 普通的点击事件
const handleClick1 = () => {console.log('点击了button按钮')
}// 获取点击事件的对象e
const handleClick2 = (e) => {console.log('点击了button按钮', e)
}// 获取自定义参数
const handleClick3 = (name) => {console.log('点击了button按钮', name)
}// 获取自定义参数,并且获取到点击事件的对象e
const handleClick4 = (name, e) => {console.log('点击了button按钮', name, e)
}function App() {return (<div>{/* 获取自定义参数,一定要写成箭头函数的形式,否则是无法使用的 */}<button onClick={handleClick1}>普通的点击事件</button><button onClick={handleClick2}>获取点击事件的对象e</button><button onClick={() => handleClick3('xiaoming')}>获取自定义参数</button><button onClick={(e) => handleClick4('xiaoming', e)}>获取自定义参数,并且获取到点击事件的对象e</button></div>);
}export default App;
6、 基础组件(函数组件)
首字母必须大写
// 项目的根组件function Button() {return <button>this is my componment</button>
}function App() {return (<div>{/* 使用组件 */}<Button></Button></div>);
}export default App;
7、 使用useState
他是一个React 的Hook(函数)。它允许我们向组件添加一个状态变量
,从而控制影响组件的渲染结果
状态变量一旦发生变化,视图UI也会跟着变化(数据驱动视图)
调用useState后会返回一个数组,数组中的第一个参数是状态变量,第二个参数是set函数,用于修改状态变量。调用useState传入的参数作为状态变量的初始值
// 项目的根组件
import { useState } from 'react'function App() {// 1.调用useState添加一个状态变量const [count, setCount] = useState(0)// 2.点击事件回调const handleClick = () => {setCount(count + 1)}return (<div><button onClick={handleClick}>{count}</button></div>);
}export default App;
使用useState的规则
useState的状态变量是不可以进行直接的修改的,直接修改视图无法进行更新。 需要调用他的set方法对数据进行替换。
8、 基础样式控制
使用行内样式,{}大括号内部必须是一个对象的形式,并且如果使用多个单词的样式,要使用驼峰命名
。例如fontSize。
使用类名的时候要注意,这里的属性名为className而不是class
// 项目的根组件
import './index.css'function App() {return (<div>{/* 行内样式控制 要使用{ 样式对象 } */}<div style={{ color: 'red' }}>this is div</div>{/* 使用类名 */}<div className="fontColor">this is div</div></div>);
}export default App;
9、 动态类名
使用模板字符串,控制类名的隐藏和现实
<li className="nav-sort">{/* 高亮类名: active */}{tabs.map(item => (<spanclassName={`nav-item ${type === item.type && 'active'}`}key={item.type}onClick={() => handleTabChange(item.type)}>{item.text}</span>))}
</li>
还可以使用第三方classnames库
,使用这个库以后可以将这种繁琐的拼接字符串判断类名的方式,转换为对象的形式进行拼接
;增加代码可读性以及优化代码开发过程。
className={`nav-item ${type === item.type && 'active'}`}
// 转换后
className={classNames('nav-item', {active: type === item.type})}
10、 操作表单,实现表单受控绑定。
相当于数据的双向绑定,实现原理依旧是使用useState,在表单的onChange事件处调用useState的第二个参数的方法,改变
import { useState } from "react"const App = () => {const [value, setValue] = useState('')return (<div><input type="text" value={value} onChange={(e) => setValue(e.target.value)}></input></div>)
}
export default App
11、 获取DOM
主要是使用useRef
import { useRef } from "react"const App = () => {const inputRef = useRef(null)const showDom = () => {console.log(inputRef)}return (<div><input type="text" ref={inputRef} /><button onClick={() => showDom()}>获取dom</button></div>)
}export default App
12、 好用的第三方库,
- uuid,用于生成随机数。
- dayjs,用于快速格式化日期。dayjs中文文档
- Lodash,高性能JS工具库,它是一个一致性、模块化、高性能的 JavaScript 实用工具库。用法见官网Lodash中文文档
- Normallize.css 初始化样式,例如padding,margin等等
三、组件通信
1、 父传子
// 父传子
// 1、父组件传递数据,子组件标签身上绑定属性
// 2、子组件接收数据,props的参数
function Son(props) {console.log(props)return <div>{props.name}</div>
}const App = () => {const name = 'this is app name'return (<div><Son name={name}></Son></div>)
}export default App
子组件参数props的说明:
- props可以传递任何类型的数据,数字、字符串、布尔、数组、对象、函数、JSX都可以进行传递;
- props是只读的属性,既单向数据流,不允许直接修改props中的值,父组件的值只能由父组件进行修改;
(1)特殊的props:children,如果在子组件的标签包裹了其他标签,那么被包裹的内容就可以在子组件的props中多出一个children属性
;
function Son(props) {console.log(props)
}const App = () => {const name = 'this is app name'return (<div><Son><span>this is span</span></Son></div>)
}export default App
2、 子传父
主要原理是应用props的特性,可以传递任何类型;父组件定义一个函数,用于接收子组件传递的参数。然后把函数传递给子组件,让子组件调用。
// 子传父
// 父组件定义一个函数,用于接收子组件传递的参数
// 然后把函数传递给子组件,让子组件调用
function Son({ onGetSonMsg }) {const sonMsg = 'this is son msg'return (<div>this is son<button onClick={() => onGetSonMsg(sonMsg)}> send</button></div>)}const App = () => {const getMsg = (msg) => {console.log(msg)}return (<div><Son onGetSonMsg={getMsg} /></div>)
}export default App
3、 借助“状态提升”
机制实现兄弟组件通信
什么是状态提升?既通过共同的父组件进行数据传递
;
import { useState } from 'react'
// 借助状态提升机制实现兄弟组件通信function A({ onGetAMsg }) {const AMsg = 'this is A msg'return (<div>this is A<button onClick={() => onGetAMsg(AMsg)}> send</button></div>)}function B({ msg }) {return (<div>this is B,{msg}</div>)
}const App = () => {const [AMsg, setAMsg] = useState('')const getAMsg = (msg) => {console.log(AMsg)setAMsg(msg)}return (<div><A onGetAMsg={getAMsg}></A><B msg={AMsg}></B></div>)
}export default App
4、 使用context机制跨层传递数据
主要原理是使用createContext
import { createContext, useContext } from 'react'
// 示例,将APP里面的数据传递到B组件
// 层级关系是 <App> <A> <B></B> </A> </App>
// 1、先使用createContext创建一个上下文对象
const MsgContext = createContext()function A() {return (<div>this is A<B></B></div>)}function B() {// 3、在底层组件通过useContext钩子函数来使用数据const msg = useContext(MsgContext)return (<div>this is B,{msg}</div>)
}const App = () => {const msg = 'this is app msg'return (<div>{/* 2、在顶层组件通过provider组件,提供数据 */}<MsgContext.Provider value={msg}>this is App<A/></MsgContext.Provider></div>)
}export default App
四、常用钩子函数介绍
- useEffect是一个React Hook函数,用于在React组件中创建
不是由事件引起而是由渲染本身引起的操作
,比如发送AJAX请求,更改DOM等等。useEffect(() =>{}, [])
- 参数1是一个函数,可以把它叫做
副作用函数
,在函数内部可以放置要执行的操作
- 参数2是一个数组(可选参),在数组里放置依赖项,不同依赖项会影响第一个参数函数的执行,
当是一个空数组的时候,副作用函数只会在组件渲染完毕之后执行一次
- useEffect的不同依赖项参数的不同执行表现
- 1、什么也不传的情况 页面初始化以及组件更新都会调用
- 2、传空数组 页面初始化会调用
- 3、传一个依赖项,只有依赖项变化的时候才会调用
import { useEffect, useState } from "react"const App = () => {const [count, setCount] = useState(0)const [sum, setSum] = useState(0)// 1、什么也不传的情况 页面初始化以及组件更新都会调用// useEffect(() => {// console.log('副作用函数执行了!!')// })// 2、传空数组 页面初始化会调用// useEffect(() => {// console.log('副作用函数执行了!!')// }, [])// 3、传一个依赖项,只有依赖项变化的时候才会调用useEffect(() => {console.log('副作用函数执行了!!')}, [count])return (<div>this is APP<button onClick={() => setCount(count + 1)}> count+{count}</button><button onClick={() => setSum(sum + 1)}> sum+{sum}</button></div>)
}export default App
- 清除副作用,例如当我们在组件初始化的时候创建一个定时器,在组件销毁的时候要清除定时器,否则会一直占用资源。
语法是在useEffect内部return一个函数,函数内部执行清除操作
。清除副作用做常见的时机是在组件销毁的时候
import { useState, useEffect } from "react"function Son() {useEffect(() => {const timer = setInterval(() => {console.log('ding...')}, 1000);return () => {console.log('组件卸载,清除副作用!')clearInterval(timer)}}, [])return <div>this is son</div>
}const App = () => {const [show, setShow] = useState(true)return (<div>{/* 模拟组件销毁 */}{show && <Son />}<button onClick={() => setShow(false)}>卸载组件</button></div>)
}export default App
4、自定义Hook函数
自定义Hook是以 use
打头的函数,通过自定义Hook函数可以用来实现逻辑的封装和复用
封装通用Hook函数的通用思路
- 生命一个以use开头的函数;
- 在函数体内封装可服用的逻辑;
- 要把组件中用到的状态或者回调return出去;
- 在那个组件重要用到这个逻辑,就在那里调用这个函数,结构赋值所用到的状态或者回调函数;
import { useState } from "react"const useShowDiv = () => {const [show, setShow] = useState(true)const onChangeShow = () => {setShow(!show)}return {show,onChangeShow}
}const App = () => {const { show, onChangeShow } = useShowDiv()// const [show, setShow] = useState(true)// const onChangeShow = () => {// setShow(!show)// }return (<div>{show && <div>this is div</div>}<button onClick={() => onChangeShow()}>切换div状态</button></div>)
}export default App
5.React Hook函数的使用规则
- 只能在组件中或者其他自定义Hook函数中调用
- 只能在组件的顶层调用,
不能嵌套在if、for、其他函数中
以上两种情况,不符合条件时候开发工具和浏览器会报错,注意一下即可。
五、Redux快速上手
1. 环境搭建
在React中使用redux,官方要求安装俩个其他插件-ReduxToolkit和react-redux
- Redux Toolkit(RTK)-官方推荐编写Redux逻辑的方式,是一套工具的集合集,简化书写方式
- 简化store的配置方式
- 内置immer支持可变式状态修改
- 内置thunk更好的异步创建
- react-redux-用来 链接 Redux和 React组件 的中间件
安装插件
npm i @reduxjs/toolkit react-redux
2. store目录结构设计
3. 使用流程
ReduxToolkit和react-redux搭配使用流程
以一个异步请求为例
// 先引入createSlice方法
import { createSlice } from "@reduxjs/toolkit"
import axios from 'axios'
// 创建store
const foodsStore = createSlice({// 名称name: 'foods',initialState: {// 设置初始值为空数组foodsList: []},reducers: {// 声明同步操作函数 actionsetFoodsList(state, action) {state.foodsList = action.payload}}
})
// 获取创建的action
const { setFoodsList } = foodsStore.actions
// 创建异步方法,异步方法的语法必须return一个方法,方法的第一个参数为dispach。
// 可用于提交action。在异步方法里面调用网络请求,将请求后的得到的数据调用同步
// 方法赋值给store
const fetchFoodsList = () => {return async (dispatch) => {const res = await axios.get('http://localhost:3004/takeaway')// 调用dispatch函数dispatch(setFoodsList(res.data))console.log(res)}
}
// 导出异步方法让外界调用
export { fetchFoodsList }const reducer = foodsStore.reducer
// 导出reducer
export default reducer
然后在store目录下的index.js文件中,收集modules下创建的store
import foodsReducer from './modules/takeaway'
import { configureStore } from '@reduxjs/toolkit'const store = configureStore({reducer: {foods: foodsReducer}
})export default store
首次使用需要在index.js里面注入store
import React from 'react'
import { createRoot } from 'react-dom/client'import App from './App'import { Provider } from 'react-redux'
import store from './store'
const root = createRoot(document.getElementById('root'))
root.render(<Provider store={store}><App /></Provider>
)
使用store中的数据,需要在组件内调用useSelector方法
const {foodsList} = useSelector(state => state.foods)
六、ReactRouter快速上手
1. 基本使用
- 创建router目录以及index.js配置文件,通过
createBrowserRouter
创建router,并导出router
import Article from '../page/Article'
import Login from '../page/Login'import { createBrowserRouter } from 'react-router-dom'const router = createBrowserRouter([{path: '/login',Component: Login},{path: '/article',Component: Article}
])export default router
- 在index.js引入路由组件RouterProvider,以及创建好的router,把router注入到路由组件中
import { RouterProvider } from 'react-router-dom'
import router from './router'<React.StrictMode><RouterProvider router={router}></RouterProvider>
</React.StrictMode>
2. 导航方式
- 声明式写法:以组件的形式进行跳转,react-router-dom提供了一个< Link /> 组件
<Link to="/login">跳转到登录</Link>
- 编程式写法:以代码的形式跳转
import { useNavigate } from 'react-router-dom'const navigate = useNavigate()
navigat('/login')
3. 路由传参
- searchParmas方式
import { useNavigate } from 'react-router-dom'const navigate = useNavigate()
// 直接用?在url后面,各个参数用&拼接
navigat('/login?id=1001&name=jack')
// 使用useSearchParams接收
import { useSearchParams } from 'react-router-dom'
// useSearchParams 返回一个数组
const [params] = useSearchParams()
const id = params.get('id')
const name = params.get('name')
- params方式,很像vue里面的动态路由,简直一模一样
import { useNavigate } from 'react-router-dom'const navigate = useNavigate()
// 直接拼接在url后面,多个参数就一直往后面拼接
navigat('/login/1001/jack')
{path: '/login/:id/:name',Component: Login}
import { useParams } from 'react-router-dom'
const params = useParams()
const id = params.id
const name = params.name
4. 嵌套路由
- 使用children配置嵌套路由
- 在需要嵌套路由的地方使用组件
<Outlet />
组件
{path: '/article',Component: Article,children: [{path: '/component1',element: <Component1/>},{path: '/component2',element: <Component2/>},]
},
5.默认二级路由
去掉二级路由中的path,换成index并设置为true就行了
{path: '/article',Component: Article,children: [{index: true,element: <Component1/>},{path: '/component2',element: <Component2/>},]
},
6.配置未找到路由的默认展示页面,既404页面
{path: '*',element: <NotFound/>},
7.两种路由模式
以上的案例都是使用的history模式,需要后端支持。
- history模式创建的router是使用createBrowserRouter;
- hash模式创建的router是使用createHashRouter,url上会拼接一个#;
七、两个联想提示配置
- 路径中使用@匹配src,要使用craco插件,因为cra既create-react-app把配置包在黑盒里面,无法直接配置。所以需要使用craco插件进行配置;
npm i -d @craco/craco
下载插件后新建craco.config.js文件,进行如下配置
const path = require("path")module.exports = {webpack: {alias: {'@': path.resolve(__dirname, 'src')}}
}
- @符号路径的联想功能
新建jsconfig.json文件
{"compilerOptions": {"baseUrl": "./","paths": {"@/*": ["src/*"]}}
}
这里也一定要修改package.json文件,修改启动指令
"scripts": {"start": "craco start","build": "craco build","test": "react-scripts test","eject": "react-scripts eject"},
八、json-server 构建测试服务
- 安装json-server,
npm i -D json-server
; - 新建一个json文件存储数据;
- 在package.json添加启动命令;追加
"server": "json-server ./server/data.json --port 8888"
"scripts": {"start": "craco start","build": "craco build","test": "react-scripts test","eject": "react-scripts eject","server": "json-server ./server/data.json --port 8888"},
文章内容为黑马程序员课程学习总结,大家感兴趣的也可以去B站看哦,老师讲的非常好
相关文章:

React保姆级教学
React保姆级教学 一、创建第一个react项目二、JSX基本语法与react基础知识1、 插值语法:2、 循环一个简单列表3、 实现简单条件渲染4、 实现复杂的条件渲染5、 事件绑定6、 基础组件(函数组件)7、 使用useState8、 基础样式控制9、 动态类名1…...

数据结构和矩阵细节用法:double、cell和complex #matlab
矩阵建立 建立矩阵用[]; 矩阵的同一行内的元素用逗号或者空格隔开; 矩阵的不同行的元素用分号隔开 eg. 矩阵 A 1 2 3 4 5 6 7 8 9 在matlab中矩阵A表示为: clc;clear; A[1,2,3;4,5,6;7,8,9]; %或者A[1 2 3;4 5 …...

12. Django 第三方功能应用
12. 第三方功能应用 因为Django具有很强的可扩展性, 所以延伸了第三方功能应用. 通过本章的学习, 读者能够在网站开发过程中快速实现API接口开发, 验证码生成与使用, 站内搜索引擎, 第三方网站实现用户注册, 异步任务和定时任务, 即时通信等功能.12.1 Django Rest Framework框…...

UnityWebRequest获取本地txt文件,其中中文乱码问题(踩坑记录)
Unity获取本地streamingassert下txt文件,遇到点问题,就是用UnityWebRequest下载一个txt文件的时候,原txt在资源管理器用notepad打开显示正常,但是Unity里调试,打印内容却是乱码, 在notepad 转存为utf-8&…...

轮到国产游戏统治Steam榜单
6月10日晚8点,《黑神话:悟空》实体版正式开启全款预售,预售开启不到5分钟,所有产品即宣告售罄。 Steam上,《黑神话:悟空》持续占据着热销榜榜首的位置。 但在《黑神话:悟空》傲人的光环下,还有一款国产游戏取得出色的成绩。 6月10日&#…...

不想搭集群,直接用spark
为了完成布置的作业,需要用到spark的本地模式,根本用不到集群,就不想搭建虚拟机,hadoop集群啥的,很繁琐,最后写作业还用不到集群(感觉搭建集群对于我完成作业来说没有什么意义)&…...

【MATLAB源码-第225期】基于matlab的计算器GUI设计仿真,能够实现基础运算,三角函数以及幂运算。
操作环境: MATLAB 2022a 1、算法描述 界面布局 计算器界面的主要元素分为几大部分:显示屏、功能按钮、数字按钮和操作符按钮。 显示屏 显示屏(Edit Text):位于界面顶部中央,用于显示用户输入的表达式和…...

Scikit-learn 基础教程:机器学习的初步指南
Scikit-learn 是一个用于数据挖掘和数据分析的机器学习库,建立在 NumPy、SciPy 和 matplotlib 之上。它提供了简单而高效的工具来进行数据分析和建模。本文将为您介绍 Scikit-learn 的安装方法、核心组件,以及如何应用这些组件进行一个简单的机器学习项目…...

开源WebGIS全流程常用技术栈
1 数据生产 1.1 uDig uDig(http://udig.refractions.net/)是一个基于Java开源的桌面应用框架,它构建在Eclipse RCP和GeoTools(一个开源的Java GIS包)上。可以进行shp格式地图文件的编辑和查看;是一个开源空间数据查看…...

前端开发之HTTP协议认识
上一篇👉: 前端开发之WebSocket通信 文章目录 1. HTTP 1.0 和 HTTP 1.1 之间有哪些区别1.连接方面:2.资源传输优化:3.缓存机制增强:4.主机头识别5.请求方法扩展 2.HTTP 1.1 和 HTTP 2.0 的区别1. 二进制分帧层:2.多路…...

力扣刷题总结 -- 数组26
76. 所有奇数长度子数组的和(简单) 题目要求: 给定一个正整数数组 arr ,计算所有奇数长度子数组的和。 子数组定义为原数组中的一个连续子序列。 返回 arr 中 所有奇数长度子数组的和 。 题目分析: 先得到所有子…...

无线MODBUS通讯模块在供水系统中的应用
一、项目背景 我国是人口大国、农业大国,同时也是贫水大国。由于大量工业废水污染了部分河流、地表的浅层水资源,并且有逐年加重的趋势,再加上农业、绿化等灌溉对水资源的大量消耗,这些因素综合作用进一步加剧了我国水资源紧缺的…...

linux为什么不是实时操作系统
Linux为什么不是实时操作系统? 从我们接触Linux系统开始,一直听到的都是它是非实时操作系统,怎么理解这个非实时呢? 我的理解,非实时,就是中断响应不及时,任务调度不及时。那么,真…...

【STM32】飞控设计
【一些入门知识】 1.飞行原理 【垂直运动】 当 mg>F1F2F3F4,此时做下降加速飞行 当 mg<F1F2F3F4,此时做升高加速飞行 当 mgF1F2F3F4 ,此时垂直上保持匀速飞行。 【偏航飞行】 ω 4 ω 2 ≠ ω 1 ω 3 就会产生水…...

MySQL CDC
一、MySQL CDC概念 MySQL CDC(Change Data Capture),即MySQL变更数据捕获,是一种能够捕获MySQL数据库中数据变化(包括插入、更新和删除操作)的技术。这些变化可以实时或准实时地同步到其他系统或服务中&am…...

手把手教你安装 Vivado2022.2(附安装包)
一、Vivado 2022.2 优势 Vivado 2022.2版本与之前的版本相比,具有以下几个显著的优势: 电源设计管理器(PDM):Vivado 2022.2引入了全新的电源设计管理器(PDM),这是一个下一代功耗评…...

旅行者1号有什么秘密?飞行240多亿公里,为什么没发生碰撞?
旅行者1号有什么秘密?飞行240多亿公里,为什么没发生碰撞? 自古以来,人类就对浩瀚无垠的宇宙充满了好奇与向往。从最初的仰望星空,到如今的深空探测,人类探测宇宙的历史发展可谓是一部波澜壮阔的史诗。 在…...

如何保护云主机安全
在数字化时代,云服务器已成为企业数据存储、处理和传输的重要工具。然而,随着其应用的广泛和深入,云服务器也面临着越来越多的安全威胁。为了应对这些威胁,白名单技术应运而生,成为保护云服务器安全的重要手段。 首先&…...

postman教程-19-mock测试
上一小节我们学习了Postman接口参数化方法,本小节我们讲解一下Postman mock测试的方法。 一、什么叫mock测试 mock测试就是在测试过程中,对某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便于测试的一种测试方法,…...

纳秒级网络库【二】技术选型
在十年之前,已经有网络产品实现7纳秒延迟,所以无需质疑是否能够实现,关键问题是:代价是什么。国内不少量化公司在招聘低延迟总线的开发人员,虽然我不知道他们具体的技术选型,从技术底层来看,并没…...

ESP32基础应用之esp32连接腾讯云并使用微信小程序控制的智能灯
文章目录 1. 项目简介1.1 功能接收1.2 使用资源1.3 测试平台 2 腾讯云物联网开发平台3 esp32设备开发3.1 准备参考例程3.2 vscode平台创建测试工程3.3 修改工程 问题总结使用PowerShell命令行终端生成的二维码不能用 1. 项目简介 1.1 功能接收 实现腾讯云创建项目与设备&…...

Unity Protobuf+RPC+UniTask
远程过程调用(RPC)协议详解 什么是RPC协议RPC的基本原理RPC的关键组件RPC的优缺点Protobuf函数绑定CallEncodeRecvDecodeSocket.Send和Recv项目地址 什么是RPC协议 远程过程调用(Remote Procedure Call,简称RPC)是一种…...

顶顶通呼叫中心中间件(mod_cti基于FreeSWITCH)-通话时长限制
文章目录 前言联系我们场景运用机器人场景普通通话场景 前言 顶顶通呼叫中心中间件限制通话时长有两种写法,分别作用于机器人场景与普通通话场景。 普通场景可分为分机互打、分机外呼手机等。 联系我们 有意向了解呼叫中心中间件的用户,可以点击该链接…...

如何将ai集成到项目中,方法二
上一篇文章:如何将ai集成到radsystems项目中,在项目中引入ai-CSDN博客 上一篇文章内容主要针对于未实现权限分离的项目,这篇文章主要来说一下权限分离的项目怎么做,以及注意的细节。 一、编写前端router.js 二、编写前端askai.vu…...

python的变量的引用与赋值的学习
看代码: a 1 # 初始化变量a,赋值为1 b a # 变量b被赋值为变量a的值,此时b的值也为1 b 2 # 变量b被重新赋值为2 print(a) # 打印变量a的值 执行过程如下: a 1:变量a被赋值为1。b a:变量b被赋值为…...

【FPGA项目】bin文件ram存取回环测试
🎉欢迎来到FPGA专栏~bin文件ram存取回环测试 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒🍹 ✨博客主页:小夏与酒的博客 🎈该系列文章专栏:FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大…...

北航数据结构与程序设计第五次作业选填题复习
选填题考的很多都是基础概念,对于巩固复习一些仡佬拐角的知识点是很有用的。非北航学生也可以来看看这些题,这一节主要是树方面的习题: 一、 我们首先需要知道一个公式 这是证明: 知道了这个公式,我们把题目中的数据…...

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第40课-实时订阅后端数据
【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第40课-实时订阅后端数据 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引…...

系统集成知识科普:核心原理与关键技术
目录 1.系统集成的核心原理 1.1 模块化原理 1.1.1 定义: 1.1.2 优势: 1.1.3 实现方式: 1.2 标准化原理 1.2.1 定义: 1.2.2 作用: 1.2.3 实践案例: 1.2.4 制定与遵循: 1.3 协同性原理…...