一天搞定React(3)——Hoots组件【已完结】

    Hello!大家好,今天带来的是React前端JS库的学习,课程来自黑马的往期课程,具体连接地址我也没有找到,大家可以广搜巡查一下,但是总体来说,这套课程教学质量非常高,每个知识点都有一个小案例,最后有一个总的美团外卖案例教学,大家可以看看我这篇文章,如果能够帮到你们,还请多多点赞o( ̄▽ ̄)d支持支持🌹,如果文章中有错误的或者是遗漏信息,可以在评论区指出或者是与我私信。我看到了消息,一定会及时更正过来∠(°ゝ°)。话不多说,直接开学💪⛽️!

     本篇教学已完结,具体可查看教程:
1. 一天搞定React(1)——React安装与配置
2. 一天搞定React(2)——JSX语法
3. 一天搞定React(3)——Hoots组件
4. 一天搞定React(4)——Redux
5. 一天搞定Recat(5)——ReactRouter(上)
6. 一天搞定React(5)——ReactRouter(下)

文章目录

  • 组件学习
    • 创建组件
    • 组件的状态
      • 修改状态
        • 【案例】B站评论
        • classNames优化
      • 状态操作表单元素
    • useRef
  • 组件通讯
    • 父子组件通讯
      • 父传子通讯
      • 简化props
    • 子到父通讯
    • 非父子通讯
      • 兄弟关系
      • 后代关系
  • useEffet的使用
    • useEffect扩展
    • useEffect应用——发送请求
      • Json-server
      • 使用axios
  • Hooks

组件学习

创建组件

src目录下新建一个App.js文件,这个App.js就是我们创建的新的组件。

其实组件就是一个函数,所以我们只需要创建函数就能完成组件的创建。

在App.js文件中编写以下内容:

  1. 创建一个函数

    const 组件名 =()=>{return(<div>App组件</div>)
    }
    
  2. 导出组件

    export default 组件名
    
  3. 回到index.js文件,导入App组件文件路径

    import 组件名 from '文件路径'
    
  4. index.js文件中使用组件

    root.render(<div><组件库 /></div>
    );
    

组件的状态

状态(state):是可以让页面内容发生变化的数据。

使用方法:useState() 函数,如果需要修改状态就调用setCount(状态最新值)函数。

image-20240719161152619

const [count, setCount] = useState(默认值)

其中第一个元素是当前状态的值,第二个元素是更新该状态的函数。

我们来写一个计数器来更好得到理解state:

import { uesState } from 'react'const App =()=>{const [count, setCount] = uesState(10)return(<div><h1>计数器:{count} </h1><button onClick={()=> setCount(count+1)}>+1</button><button onClick={()=> setCount(count-1)}>-1</button></div>)
}
export default App

修改状态

规则:不要直接修改当前状态的值,应该创建新值。

注意:如果没有遵循该规则,会导致报错或组件无法重新渲染

如图:image-20240719165054282

在数组类型也是符合这种规则,如图:

image-20240719165151883

扩展:...list这个是表示之前的元素

setList([...list,‘新的内容'])
【案例】B站评论

我们要实现下图👇案例

image-20240719170323295

具体内容要求是有:

  1. 使用组件搭建结构
  2. 导航Tab的渲染和操作
  3. 评论列表的渲染和操作

安装Sass包

在这个项目当中我们需要使用到Sass更好的绘制样式形状,所以会用到Sass。如果你还不会Sass的话,可以跟我这之前的写过的一篇文章进行学习,相信你很快就能上手并熟练运用的💪⛽️

文章:一天搞定前端必备开发技能 (2)——less和Sass预处理器的使用_项目里嵌入 less 预处理器-CSDN博客

安装命令:

npm i sass

之后再src文件夹中创建一个app.scss文件用来编写sass样式。

之后我们在App.js文件导入scss文件和图片

导入图片

使用本地图片,需要手动导入。

❌不能像html一样直接在src导入图片路径

import 图片名称 from "图片路径"const App =()=>{return(//使用图片<img src={"图片名称"} alt="图片备注"></img>)
}
export default App

在这里我准备好了模版结构和样式给大家,大家直接复制粘贴到App.js文件当中即可;

🔗链接:B站评论案例笔记.md

注意⚠️:图片没有提供给大家,在代码中如果涉及到图片的请自行修改🌺。

组件结构搭建完成之后,我们就可以开始编写交互逻辑啦。

一共要实现以下👇三个功能:

  1. 根据状态渲染评论列表
//评论列表数据
const defaultList = [{//评论idrpid: 3,//用户信息user: {uid: "13258165",avatar: "https://未知信息",uname: "周杰伦",},//评论内容content: "哎哟,不错哦",//评论时间ctime: "10-1808:15",//喜欢数量like: 98,//0:未表态 1:喜欢 2:不喜欢action: 0,},];

使用useState来修改状态

const App=()=>{const[list,setList] = useState(defaultList)
}

列表渲染

<div classNaem="reply-list">{/*评论区*/}{list.map(item=>{return 列表项目})}
</div>
⚠️不要忘记了给每一个列表项添加key属性

image-20240719181606487

然后将这些评论编程动态的:

  • 评论头像image-20240719181651526

  • 评论名称image-20240719181711687

  • 评论事件image-20240719181751290

  • 喜欢数量image-20240719181822720

然后评论列表的渲染就基本完成了

  1. 删除评论

删除按钮的特性就是只有自己发表的评论才能够删除的,那么如何来实现呢?那就是使咱们登录用户的ID来索引判断是否是自己发表的评论。

{user.uid === item.user.uid &&() <span className="delete-bt">删除</span>)}

创建删除评论函数

//先给删除按钮绑定一个点击事件
onClick={onDelete(item.rpid))//删除评论
const onDelete=rpid=>{console.log(rpid)
}

最后用数组的过滤方法删除掉渲染

//删除评论
const onDelete=rpid=>{setList(list.filter(item=> item.rpid !== rpid))//如果要删除数组中的元素,需要调用 filter方法,并且一定要调用setList
}
  1. 喜欢和不喜欢

通过传入的action来判断是否是喜欢还是不喜欢。

image-20240719183954662

绑定点击事件

onClick={() =>onLike(item.rpid)}//创建一个喜欢的函数
const onLike=rpid=>{console.log(rpid)
}

高亮的效果显示其实就是一个取反的操作;喜欢的数量改变,还是一样先拿到action,如果是喜欢的话,就让item.like进行加减。

image-20240719184351543

不喜欢渲染也是一样的,这里我就不过多赘述啦!

image-20240719184457959

classNames优化

项目开发中,当多个类名都是动态的,手动处理会变得非常困难。

如果有多个类别都是动态的,那这个时候再来进行手动处理呢,会变得非常的困难,比如咱们来看一个例子,这边是我们经常用的一种类别处理的方式。但如果再有一个。也是动态的,你可能需要。再写一个三元表达式。3个第4个呢,再手动。那有没有更好的方式呢?

<button className={disabled ?'btnbtn-disabled':'btn'}></button>

今天我们就来学习使用classnames包来优化类名处理。

  1. 安装包

    npm i classnames
    
  2. 导包

    import classNames from 'classnames'
    

使用方法:

咱们直接上案例来进行学习

import classNames from 'classnames'
const App =()=>{// 是否禁用const [disabled,setDisabled] = useState(false)// 大小const [size,setSize] =useState('small')return(<div><button>按钮</button><hr/><div>操作:<button onClick={()=> setDisabled(true)}>禁用</button><button onClick={()=> setSize('small')}>变小</button><button onClick={()=> setSize('large')}>变大</button></div></div>)
}
export default App

以上👆就是我们会对这个按钮,给它来去加一些相应的样式,那并且这边,我还准备了两个状态,一个表示是否禁用一个。是按钮的大小,然后接下来呢,咱们还有分别有3个按钮进行控制。

  1. 如果类名一直都有的,就在函数参数内写好

    <button className={classNames('一直都用的class')}>按钮</button>
    
  2. 使用逻辑运算(适合处理单个类名)

    //语法模版
    <button className={className('一直都用的class',条件1 && ‘样式1’)}>按钮</button>
    
    //联系案例
    // 还需要联系上面的useState状态来判断const [disabled,setDisabled] = useState(false)<button className={classNames('btn',disabled && 'btn-disabled')}>按钮</button>
    

    这里classNames函数会根据disabled的值来决定是否添加'btn-disabled'这个类名。如果disabledtrueclassName将会是'btn btn-disabled';如果disabledfalseclassName将会是'btn'

  3. 使用对象语法(适合处理多个类名)

    //语法模版
    <button className={className('一直都用的class',{'样式1':条件1,'样式2':条件2,'样式3':条件3,
    })}>按钮</button>
    
    //联系案例// 是否禁用const [disabled,setDisabled] = useState(false)// 大小const [size,setSize] =useState('small')const [disabled,setDisabled] = useState(false)<button className={className('btn',{})}>按钮</button>
    

    注意⚠️:

    useState(false) 表示初始状态 disabled 的值被设置为 falsesetDisabled 是一个函数,你可以在组件中调用它来更新 disabled 的状态。所以,初始时 disabled 的取值是 false

完整代码:

import {useState} from 'react'
import classNames from 'classnames'
// import 'App.css'; // 导入CSS模块
const App =()=>{// 是否禁用const [disabled,setDisabled] = useState(false)// 大小const [size,setSize] =useState('small')return(<div><button className={classNames('btn',{'btn-disabled':disabled,'btn-small':size === 'small','btn-large':size === 'large',})}>按钮</button><hr/><div>操作:<button onClick={()=> setDisabled(true)}>禁用</button><button onClick={()=> setSize('small')}>变小</button><button onClick={()=> setSize('large')}>变大</button></div></div>)
}
export default App

状态操作表单元素

步骤:

  1. 准备一个状态

    cosnt [value,setValeue] = useState('')
    
  2. 实现数据到是视图的绑定,使用value值绑定状态值

  3. 实现视图到数据的绑定,使用onChange属性设置状态

    <input value={value} onChange={e => setValue(e.target.value)}
    
    • e.target:拿到dom对象
  4. 调用setValue()函数来更新状态

案例:绑定复选框

import { useState } from "react";const App = () => {const [checked, setChecked] = useState(false);return (<div><inputtype="checkbox"checked={checked}onChange={(e) => setChecked(e.target.checked)}/>{checked ? "选中了" : "未选中"}</div>);
};
export default App;

注意⚠️:valueonChange的值需要同时出现,不然没法实现绑定事件.

这种模式在React中有一个专业的术语:受控组件.所谓的受控组件就是收到React状态控制的表单元素.

useRef

在React组件中操作DOM,需要使用useRef,分为两步:

  1. 创建一个ref对象

    const 对象名 = useRef(null)
    
  2. 与JSX绑定

    <input ref={对象名}/>
    
  3. 根据业务进行DOM操作:通过对象名.current.DOM属性拿到DOM对象

案例:

import { useRef } from "react";const inputRef = useRef(null)<input ref={inputRef}/><button onClick={()=>alert(inputRef.current.value)}>获取文本框的值</button>

组件通讯

使用场景:一个组件需要使用另一个组件的数据。

根据组件之间的层级关系,常见的React组件通讯分为3种:

  1. 父子组件通讯
  2. 非父子组件通信
  3. 状态管理工具

父子组件通讯

父传子通讯

父组件提供数据,通过props传递给子组件使用。

作用:给组件传递数据,是React组件通讯的基础。

使用步骤:

  1. 传递props:在组件标签上添加属性

    <组件名 定义传递属性="属性值"/>
    
  2. 接受props:通过参数拿到

    const 组件名 = props =>{return(<标签 属性={props.定义传递属性}/>)
    }
    

案例:

const Study = props=>{return (<div style={{backgroundColor:'red' , width:props.w, height:props.h }}></div>)
}
//使用组件
const App = () => {
return (<div><Study w={100} h={200} />{/* <Study w={"100px"} h={"200px"} />  */}</div>);
};
export default App;

在React中,属性的传递方式有两种:字符串和JavaScript表达式。在上面的例子中,<Study w="100px" h="200px" /><Study w=100 h=200 /> 表现的行为是不同的:

  1. 字符串形式 (<Study w="100px" h="200px" />):
    • 这里的 wh 属性被传递为字符串。即使它们看起来像是数字后面跟着单位(例如 "100px"),它们在JavaScript中被当作字符串处理。
    • 这意味着在组件内部,props.wprops.h 将会是字符串类型的值,包含单位。
  2. JavaScript表达式形式 (<Study w=100 h=200 />):
    • 这里的 wh 属性直接作为JavaScript表达式传递,没有引号。这意味着它们将按照它们在JSX中声明的类型传递给组件。

在组件中如果期望 props.wprops.h 是带有单位的CSS尺寸值。最好还是在设置样式之前将数字转换为带有单位的字符串。

例如,在组件内部添加逻辑来添加单位:

const Study = props => {const width = `${props.w}px`; // 假设props.w是数字,这里添加了'px'单位const height = `${props.h}px`; // 同上return (<div style={{backgroundColor: 'red', width, height }}></div>);
};

在这个例子中,无论 props.wprops.h 是数字还是字符串,我们都确保它们被转换为带有单位的字符串,以便正确地应用CSS样式。

注意⚠️:这里运用到了模板字符串(也称为模板字面量)的语法。模板字符串允许你嵌入表达式到字符串字面量中,用${}包裹表达式,然后通过插值表达式的值。

简化props

我们还可以对props对象进行简化,由于props是一个对象,我们这里可以直接通过结构的方式直接拿到传过来的值。然后就能删掉props.

const Study = ({w,h})=>{return (<div style={{backgroundColor:'red' , width:w, height:h }}></div>)
}
//使用组件
const App = () => {
return (<div><Study w={100} h={200} /></div>);
};
export default App;

在实际开发中我们推荐使用简化方式,另外还可以在结构里面添加一个默认值。

const Study = ({w=10,h=20})=>{return (<div style={{backgroundColor:'red' , width:w, height:h }}></div>)
}
//使用组件
const App = () => {
return (<div><Study w={100} h={200} />对比,上面一个是修改了默认值,下面一个是直接默认值<Study/></div>);
};
export default App;

image-20240721125251552

子到父通讯

语法模版:

  1. 父组件准备修改数据的函数,传递给子部件

    //父组件
    const 修改数据函数名 = 参数=>{}
    <标签名 修改数据函数名={修改数据函数名}></标签名>	//将修改数据函数传递给子组件
    
  2. 子组件调用函数,将数据作为参数回到父组件

    //子组件
    const 组件名 =({参数,修改数据函数名})=>{return <标签名 onClick ={()=>修改数据函数名(值)}></标签名>
    }	//子组件调用函数
    

案例:

App.css文件:

.container {display: flex; /* 设置为Flex容器 */align-items: center; /* 垂直居中对齐 */
}
.yes { background-color: #c0e2f0;width: 100px;height: 30px;border: 1px solid black;margin:5px;text-align: center;
}
.no {background-color: #f6c8c8;
}

App.js文件:

import { useState } from "react";
import classNames from "classnames";
import "./App.css";
// 子组件
const Son = ({ id, num,change }) => {//子组件调用函数changereturn (<div className="container"><div className={classNames("yes", id && "no")}>{String(id)}</div><button onClick={() => change(num)}>点击按钮变换颜色</button>{/*change(id)将数据作为参数回到父组件 */}</div>);
};// 数据
const datas = [{num: 1,id: true,},{num: 2,id: true,},{num: 3,id: false,},
];// 父组件
const App = () => {const [data, setData] = useState(datas); //准备默认值const change = (num) => {//父组件准备修改数据的函数setData(data.map((item) => {if (item.num === num) {return {...item,id: !item.id,};}return item}));};return (<div>{data.map((item) => {return <Son key={item.num} num= {item.num} id={item.id} change={change} />;//遍历渲染 change={change}传递给子部件})}</div>);
};
export default App;

最后实现的案例效果:image-20240721180009982

我们还可以在遍历渲染的时候再次优化代码:

<div>{data.map((item) => {// return <Son key={item.num} num= {item.num} id={item.id} change={change} />;return <Son key={item.num} {...item} change={change} />;//{...item}表示数据中的其他属性分别传递给子组件})}</div>

非父子通讯

兄弟关系

根据组件之间的层级关系,常见的有两种情况:

image-20240721180627027

  1. 找到父组件,提供要共享的数据
  2. 通过父到子通讯,来展示好友名称
  3. 通过子到父通讯,来修改选中的好友

在React中有专门的一个术语来形容:状态提升
如果两个兄弟组件要通讯,就把共享数据提升到公共父组件中

后代关系

React的Context API提供了一种方式,允许你共享那些对于组件树中许多组件都必不可少的数据,例如用户偏好、地区设置、主题等,而不必通过每一层组件手动传递props。

Context(上下文):范围,无视组件层级关系,
跨组件通讯。

  1. 创建Context对象

    const 对象名 = createContext()
    
  2. 划定范围,提供共享数据

    <对象名.Provider value={共享数据}>父组件
    </对象名.Provider>
    
  3. 范围内的组件,获取共享数据

    const 共享数据 = useContext(对象名)
    

案例:共享消息

import React, { createContext, useState, useContext } from 'react';// 创建Context对象
const MessageContext = createContext();// 创建Provider组件
const MessageProvider = ({ children }) => {const [message, setMessage] = useState('Hello, World!');// 更新消息的函数const updateMessage = (newMessage) => {setMessage(newMessage);};return (<MessageContext.Provider value={{ message, updateMessage }}>{children}</MessageContext.Provider>);
};// 创建子组件
const MessageDisplay = () => {const { message, updateMessage } = useContext(MessageContext);return (<div><p>{message}</p><button onClick={() => updateMessage('New Message')}>Change Message</button></div>);
};// 创建另一个子组件
const AnotherComponent = () => {const { message } = useContext(MessageContext);return (<div><h2>Another Component</h2><p>Message from context: {message}</p></div>);
};// 应用的顶层组件
const App = () => {return (<MessageProvider><div><MessageDisplay /><AnotherComponent /></div></MessageProvider>);
};export default App;

代码解释:

  1. 创建Context: 使用 createContext 创建一个 MessageContext
  2. 创建Provider: MessageProvider 组件使用 useState 钩子来管理消息状态,并提供了一个 updateMessage 函数来更新消息。它通过 MessageContext.Provider 将这些值提供给子组件。
  3. 创建子组件:
    • MessageDisplay 组件使用 useContext 钩子从 MessageContext 获取消息和更新函数,并显示消息。它还提供了一个按钮来更改消息。
    • AnotherComponent 组件也使用 useContext 钩子从 MessageContext 获取消息,并显示它。
  4. 应用的顶层组件: App 组件使用 MessageProvider 来包裹 MessageDisplayAnotherComponent,确保它们可以访问到Context中的数据。

useEffet的使用

useEffect的作用:在组件生命周期的三个阶段(挂载更新卸载),执行网络请求、浏览器API等操作。这些操作,也叫:副作用😭。

语法:useEffect(Effect函数,依赖项数组)

  • Effect函数:副作用代码
  • 依赖项数组:控制Effect函数的执行时机(可选填)【一般在使用动态数据的时候使用,在更新时用的最多】

生命周期三个阶段:

  • 挂载时:

    useEfect(()=>{//挂载操作代码
    },[])
    
  • 更新时:

    useEffect(()=>{//更新操作代码
    },[依赖项数组])
    

    注意⚠️:更新时调用方式会在组件挂载以及更新时都会执行。

  • 卸载时:

    useEffect(()=>{return()=>{//卸载操作代码}
    },[])
    

    案例:计数器组件

    这个组件将展示一个计数器,每次点击按钮时计数器会增加。同时,组件会在挂载时打印一条消息,在更新时打印另一条消息,并在卸载时清理资源。

    import React, { useState, useEffect } from 'react';function Counter() {const [count, setCount] = useState(0);// 挂载时执行的副作用useEffect(() => {console.log('组件挂载');return () => {console.log('组件卸载');};}, []); // 空依赖项数组,仅在挂载时执行// 更新时执行的副作用useEffect(() => {console.log(`计数器更新为:${count}`);}, [count]); // 依赖项数组包含 count,每当 count 更新时执行return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
    }export default Counter;
    

    代码解释:

    1. 状态初始化: 使用 useState 钩子初始化计数器状态 count
    2. 挂载时的副作用: 第一个 useEffect 没有依赖项数组,因此它只在组件挂载时执行一次。它在控制台中打印一条消息,并在组件卸载时执行返回的函数,打印另一条消息。
    3. 更新时的副作用: 第二个 useEffect 依赖于 count。每当 count 更新时,这个 useEffect 都会重新运行,并在控制台中打印新的计数器值。
    4. 渲染UI: 组件渲染一个段落和一个按钮。按钮的点击事件处理器会调用 setCount 函数,从而更新 count 状态。

    这个示例展示了 useEffect 如何在组件的不同生命周期阶段执行代码,以及如何通过依赖项数组控制副作用的执行。

useEffect扩展

推荐:一个useEffect负责一个完整功能

useEffect(()=>{//更新操作代码(这里直接用更新来代替挂载)return()=>{//卸载操作代码}
},[依赖项数组])

依赖项说明:什么样的数据才能说明是依赖项呢?

指定依赖项的原则:Effect函数中用到的,并且是可变的值。(例如:props/state/组件中创建的变量等)

以下是一个简单的例子,演示了如何使用 useEffect 来实现一个组件的挂载和卸载操作:

import React, { useState, useEffect } from 'react';function Clock() {// 组件状态,用于显示时间const [time, setTime] = useState(new Date().toLocaleTimeString());// 使用 useEffect 钩子来处理副作用useEffect(() => {// 定义一个更新时间的函数const updateTime = () => {setTime(new Date().toLocaleTimeString());};// 设置定时器,每秒更新时间const timer = setInterval(updateTime, 1000);// 这是 effect 的清理函数,会在组件卸载时执行return () => {clearInterval(timer);};}, []); // 空的依赖项数组意味着这个 effect 只在挂载时运行一次// 渲染时显示当前时间return (<div>The time is: {time}</div>);
}export default Clock;

在这个例子中:

  • Clock 组件显示当前的时间,并且每秒更新一次。
  • useState 钩子用于创建 time 状态变量,初始值为当前的本地时间字符串。
  • useEffect 钩子用于设置一个定时器,该定时器每秒调用 updateTime 函数来更新时间。
  • 定时器通过 setInterval 创建,并在 useEffect 的返回函数中清除,以确保在组件卸载时不会继续运行。
  • 依赖项数组是空的 [],这意味着 useEffect 只在组件挂载时运行一次,不会在更新时重新运行。

useEffect应用——发送请求

场景:组件初次渲染时,发送请求获取数据。

步骤:

  1. 调用useEffect,依赖项为空数组
  2. 创建新函数,在该函数上使用async并调用
  3. 发送请求,通过await获取到数据,然后使用
useEffect(()=>{const 函数名 = async()=>{await}函数名()	//调用函数
},[])

Json-server

使用json-server提供一个接口

image-20240721224015809

使用axios

安装命令

npm i axios
useEffect(()=>{const 函数名 = async()=>{const res = await axois get('接口地址')setState(res.data)	//更新到状态State里面}函数名()	//调用函数
},[])

Hooks

ReactHooks是以use开头的函数,比如,useState/useEffect/useContext等。

Hooks(钩子):为组件提供不同的React特性,比如,useStateHook为组件提供状态。

使用规则:只能在组件的顶层调用,不能嵌套在if、for、其他函数中。

原理:React组件依赖Hooks的调用顺序,必须保证所有Hooks,在每次渲染时,调用顺序一致。

image-20240721225454872

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3267735.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构经典测试题4

1. #include <stdio.h> int main() { char *str[3] {"stra", "strb", "strc"}; char *p str[0]; int i 0; while(i < 3) { printf("%s ",p); i; } return 0; }上述代码运行结果是什么&#xff1f; A: stra strb strc B: s…

Rocky/Centos Linux安装Code-server,并注册成服务自启动

文章目录 Rocky/Centos Linux安装Code-server&#xff0c;并注册成服务自启动介绍安装1. 下载压缩包2. 解压缩3. 执行启动命令4. 浏览器访问5. 开机自启动 Rocky/Centos Linux安装Code-server&#xff0c;并注册成服务自启动 介绍 VS Code Server是微软推出的VSCode风格的Web…

谷歌AI拿下IMO奥数银牌!6道题轻松解出4道~

本周四&#xff0c;谷歌DeepMind团队宣布了一项令人瞩目的成就&#xff1a;&#xff1a;用 AI 做出了今年国际数学奥林匹克竞赛 IMO 的真题&#xff0c;并且距拿金牌仅一步之遥。这一成绩不仅标志着人工智能在数学推理领域的重大突破&#xff0c;也引发了全球范围内的广泛关注和…

私域电商丨软件系统开发中,一定要避开的几个坑,看懂少很多弯路

文丨微三云胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 大家好&#xff0c;我是软件开发胡佳东&#xff0c;每天为大家分享互联网资讯干货&#xff01; 在数字化时代的今天&#xff0c;软件开发是已经成为推动科技进步和商业发展的重要…

vmware虚拟机安装linux没有IP地址

直接设置固定IP 1、在虚拟机菜单栏选择编辑&#xff0c;然后点击虚拟网络编辑器 2、选择Vmnet8 Net网络连接方式&#xff0c;随意设置子网IP 3、点击NAT设置页面&#xff0c;查看子网掩码和网关&#xff0c;修改静态IP会用到 4、打开电脑控制面板–网络和Internet–网络连…

面试常考Linux指令

文件权限 操作系统中每个文件都拥有特定的权限、所属用户和所属组。权限是操作系统用来限制资源访问的机制&#xff0c;在 Linux 中权限一般分为读(readable)、写(writable)和执行(executable)&#xff0c;分为三组。分别对应文件的属主(owner)&#xff0c;属组(group)和其他用…

前端知识笔记之HTML

1.标签元素与属性&#xff0c;注意事项 2.多级标签排序List&#xff0c;无顺序&#xff08;Ul&#xff09;和有顺序(Ol) 3.HTML页面结构 4.页面跳转&#xff0c;注意#是统一页面的跳转 5.图片、视频、音频 标签 6.前端表单与后端方法 数据接收的demo 7.常见表单项 8.注意日期类…

Python爬虫知识体系-----Urllib库的使用

数据科学、数据分析、人工智能必备知识汇总-----Python爬虫-----持续更新&#xff1a;https://blog.csdn.net/grd_java/article/details/140574349 文章目录 1. 基本使用2. 请求对象的定制3. 编解码1. get请求方式&#xff1a;urllib.parse.quote&#xff08;&#xff09;2. ur…

Linux 安装 GDB (无Root 权限)

引入 在Linux系统中&#xff0c;如果你需要在集群或者远程操作没有root权限的机子&#xff0c;安装GDB&#xff08;GNU调试器&#xff09;可能会有些限制&#xff0c;因为通常安装新软件或更新系统文件需要管理员权限。下面我们介绍可以在没有root权限的情况下安装GDB&#xf…

谷粒商城-性能压测

1.压力测试 在项目上线前对其进行压力测试(以每个微服务为单元) 目的:找到系统能承载的最大负荷,找到其他测试方法更难发现的错误(两种类型:内存泄漏,并发与同步). 1.性能指标 响应时间(Response Time (RT)): 响应时间 指用户从客户端发起一个请求开始,到客户端接收到从服务…

2023IMO预选题几何第5题

在锐角 △ A B C \triangle ABC △ABC 中, ω ω ω 是外接圆, O O O 是外心. D D D, E E E 分别是 ω ω ω 上不同于 B B B, C C C 的点, 满足 B D BD BD ⊥ A C AC AC, C E CE CE ⊥ A B AB AB. 设直线 C O CO CO, A B AB AB 交于点 X X X, 直线 B O BO BO,…

怎样在 Nginx 中配置基于请求客户端指纹识别数据的路由?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; 文章目录 怎样在 Nginx 中配置基于请求客户端指纹识别数据的路由 怎样在 Nginx 中配置基于请求客户端指纹识别数据的路由 在当今数字化的世界中&#xff0c;网站和应用程…

mac M1安装Roop教程及所遇到的问题

1.安装miniconda&#xff0c;下载地址&#xff1a; 按 Python 版本划分的最新 Miniconda 安装程序链接&#xff1a;https://docs.anaconda.com/miniconda/miniconda-other-installer-links/ 下载后直接默认安装即可。 我用的是&#xff1a;Python3.10对应的Miniconda 2.下载…

GIT新手提交操作

1、创建一个本地分支 进入Xshell已经拉取的该项目的项目代码路径下执行git checkout -b 姓名全拼音&#xff0c;例如&#xff1a;git checkout -b xiewei&#xff0c;当前显示已创建。 cuihengyidell-PowerEdge-T550:~/SVN/Git_R11/R11_V4.02.0_Source$ git checkout -b cuih…

[数据集][目标检测]躺坐站识别检测数据集VOC+YOLO格式9488张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;9488 标注数量(xml文件个数)&#xff1a;9488 标注数量(txt文件个数)&#xff1a;9488 标注…

STM32开发环境配置记录——关于PlatformIO + VSCode + CubeMX的集成环境配置

目录 前言 介绍 PlatformIO STM32CubeMX Visual Studio Code 正文 使用STM32CubeMX生成PlatformIO可以支持的Makefile文件 1. 选择目标引脚并配置 2. 配置时钟树 3. [关键&#xff01;调试则需要&#xff1a;]选择调试器类型 4. 选择对应的目标IDE配置代码与文件 使…

Spring Boot中如何实现全链路调用日志跟踪?

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 引言 在Spring Boot中实现全链路调用日志跟踪&#xff0c;主要依赖于Mapped Diagnostic Context&#xff08;MDC&#xff09;功能。MDC是一种用于在多线程条件下记录日志的功能&#xff0c;它可以看作是与当…

【Unity】关于Luban的简单使用

最近看了下Luban导出Excel数据的方式&#xff0c;来记录下 【Unity】关于Luban的简单使用 安装Luban开始使用UnityLubanC# 扩展 安装Luban Luban文档&#xff1a;https://luban.doc.code-philosophy.com/docs/beginner/quickstart 1.安装dotnet sdk 8.0或更高版本sdk 2.githu…

Java面经之Java并发

进程&#xff1a;程序的一次执行 线程&#xff1a;一个进程在执行的过程可以产生多个线程 多个线程共享进程的堆和方法区资源&#xff0c;但每个线程有自己的程序计数器、虚拟机栈、本地方法栈 其中程序计数器是为了线程切换后恢复到正确的执行位置&#xff1b;虚拟机栈和本地…

Zabbix自定义监控内容部署+邮件报警+Zabbix自愈+Zabbix批量添加主机

一、自定义监控项 1.1自定义监控项原理 1&#xff09;先明确获取监控指标数据的命令或脚本; 2&#xff09;在被监控主机配置文件子目录&#xff08;/etc/zabbix/zabbix_agent2.d/)中创建以.conf后缀的监控项配置文件&#xff0c;自定义获取监控指标数据的键值&#xff1b; …