React(三):脚手架、组件化、生命周期、父子组件通信、插槽、Context
React(三)
- 一、脚手架安装和创建
- 1.安装脚手架
- 2.创建脚手架
- 3.看看脚手架目录
- 4.运行脚手架
- 二、脚手架下从0开始写代码
- 三、组件化
- 1.类组件
- 2.函数组件
- 四、React的生命周期
- 1.认识生命周期
- 2.图解生命周期
- (1)Constructor
- (2)componentDidMount
- (3)componentDidUpdate
- (4)componentWillUnmount
- 3.演示生命周期
- 4.不常用的生命周期
- 五、父子组件通信
- 1.父传子props接收
- 2.props接收数据类型限制和默认值
- 3.子传父用函数
- 4.案例练习
- 六、React插槽效果
- 1.通过props.children传递
- 2.通过props直接传递
- 3.作用域插槽
- 七、祖孙及更深层次的通信
- 1.{...props}解构
- 2.Context的使用(类组件)
- 3.Context的使用(函数组件)
一、脚手架安装和创建
首先安装Node:保姆级别教程
1.安装脚手架
在git bash中输入: npm install create-react-app -g
,然后输入create-react-app --version
,如果能正常显示版本号,那么安装就成功了。
2.创建脚手架
目录下右键 => git bash => create-react-app 项目名
=> 回车等几分钟就欧了。
注意项目名不能包含大写字母。
3.看看脚手架目录
4.运行脚手架
脚手架目录下 => npm run start
,然后就可以看到非常帅气的大花。
二、脚手架下从0开始写代码
没啥用的先删了,我们自己搭建src中的文件:
好,那么接下来我们重新写一下src里面的文件:
index.js
//重写react代码,并且通过react渲染出来对应的内容
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.querySelector('#root'));
root.render(<App/>);
App.jsx
import React from 'react';
import HelloReact from './Components/HelloReact';class App extends React.Component {constructor() {super();this.state = {name:'zzy'}}render() {return (<div><h2>奥里给</h2><button>按钮</button><HelloReact/></div>)}
}export default App;
HelloReact.jsx
import React from 'react';class HelloReact extends React.Component {constructor() {super();this.state = {name: 'react'}}render() {return (<div><h2>Hello React!</h2></div>)}
}export default HelloReact
三、组件化
1.类组件
类组件的定义有如下要求:
- 组件的名称是大写字符开头(无论类组件还是函数组件)
- 类组件需要继承自
React.Component
- 类组件必须实现
render
函数
使用class定义一个组件:
- constructor是可选的,我们通常在constructor中初始化一些数据;
this.state
中维护的就是我们组件内部的数据;render()
方法是 class 组件中唯一必须实现的方法;
class App extends React.Component {constructor() {super();this.state = {name:'zzy'}}render() {return [<div><h2>奥里给</h2><button>按钮</button><HelloReact/></div>,<div></div>]}
}
render函数的返回值可以是什么?
- React 元素:
通常通过 JSX 创建。
例如,<div />
会被 React 渲染为 DOM 节点,<MyComponent />
会被 React 渲染为自定义组件;
无论是<div />
还是<MyComponent />
均为 React 元素(通过creatElement创建出来的东西)。 - 数组或 fragments:使得 render 方法可以返回多个元素。
- Portals:可以渲染子节点到不同的 DOM 子树中。
- 字符串或数值类型:它们在 DOM 中会被渲染为文本节点
- 布尔类型或 null:什么都不渲染
2.函数组件
函数组件是使用function来进行定义的函数,只是这个函数会返回和类组件中render函数返回一样的内容。
函数组件有自己的特点(当然,后面我们会讲hooks,就不一样了):
- 没有生命周期,也会被更新并挂载,但是没有生命周期函数;
- 没有
this
(组件实例); - 没有内部状态(
state
);
我们来定义一个函数组件:
//函数式组件
function App() {//返回的东西和render返回的是一样的。return <h1>我是一个函数组件</h1>
}export default App;
四、React的生命周期
1.认识生命周期
生命周期的概念和vue中是一样的,只不过在React中钩子更少一些。
React内部为了告诉我们当前处于哪些阶段,会对我们组件内部实现的某些函数进行回调,这些函数就是生命周期函数:
- 比如实现componentDidMount函数:组件已经挂载到DOM上时,就会回调;
- 比如实现componentDidUpdate函数:组件已经发生了更新时,就会回调;
- 比如实现componentWillUnmount函数:组件即将被移除时,就会回调;
我们可以在这些回调函数中编写自己的逻辑代码,来完成自己的需求功能;
我们谈React生命周期时,主要谈的类的生命周期,因为函数式组件是没有生命周期函数的;(后面我们可以通过hooks来模拟一些生命周期的回调)
2.图解生命周期
这张图画的还是非常不错的,在这里插入代码片
(1)Constructor
如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。
constructor中通常只做两件事情:
1、通过给 this.state
赋值对象来初始化内部的state;
2、为事件绑定实例(this);
(2)componentDidMount
componentDidMount()
会在组件挂载后(插入 DOM 树中)立即调用。
componentDidMount中通常进行哪里操作呢?
依赖于DOM的操作可以在这里进行;
在此处发送网络请求就最好的地方;(官方建议)
可以在此处添加一些订阅(会在componentWillUnmount取消订阅);
(3)componentDidUpdate
componentDidUpdate()
会在更新后会被立即调用,首次渲染不会执行此方法。
当组件更新后,可以在此处对 DOM 进行操作;
如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求;(例如,当 props 未发生变化时,则不会执行网络请求)。
(4)componentWillUnmount
componentWillUnmount()
会在组件卸载及销毁之前直接调用。
在此方法中执行必要的清理操作;
例如,清除 timer,取消网络请求或清除在 componentDidMount()
中创建的订阅等;
3.演示生命周期
我们创建累组件App,并将HelloReact组件作为它的子组件:
App组件:
class App extends React.Component {constructor() {console.log('APP-constructor')super();this.state = {name: 'zzy'}}changeData() {this.setState({name: 'ht'})}render() {console.log('App-render');const { name } = this.state;return (<div><h2>{name}</h2><button onClick={() => this.changeData()}>点击修改数据</button>{name == 'zzy' && <HelloReact />}</div>)}componentDidMount() {console.log('App-componentDidMount')}componentDidUpdate() {console.log('App-componentDidUpdate')}
}
HelloReact组件
class HelloReact extends React.Component {constructor() {console.log('HR-constructor')super();this.state = {name: 'react'}}render() {console.log('HR-render')return (<div><h2>Hello React!</h2></div>)}componentDidMount() {console.log('HR-componentDidMount')}componentDidUpdate() {console.log('HR-componentDidUpdate')}componentWillUnmount() {console.log('HR-componentWillUnmount')}
}
让我们看一下控制台的输出:
不难看出生命周期的一个顺序:
对于挂载来说:父组件constuctor
=> 父组件render
=> 子组件constructor
=> 子组件render
=> 子组件挂载完毕 => 父组件挂载完毕
对于更新来说,如果要让子组件从页面上消失,那么点击跟新执行父组件render函数后子组件会走销毁的钩子,然后走子组件更新完毕的钩子,和图是一样滴。
4.不常用的生命周期
请参考:React官方文档生命周期
五、父子组件通信
在了解React中的组件通信前,我们先搭建一个组件嵌套结构:
class App extends React.Component {render() {const { name } = this.state;return (<div><Header/><Main/><Footer/></div>)}
}
Footer和Header长得一样
class Header extends React.Component {render() {return (<div><h2>Header</h2></div>)}
}
class Main extends Component {render() {return (<div><h2>Main</h2><Banner/><ProductList/></div>)}
}
class Banner extends Component {render() {return (<div>Banner</div>)}
}
class ProductList extends Component {render() {return (<div>ProductList</div>)}
}
1.父传子props接收
这里我们主要研究Main
给Banner或ProductList
组件传数据,我们可以准备一些静态数据。
和vue一样,在子组件标签处写属性名,传变量用{}
,传其他用字符串。
class Main extends Component {constructor() {super();this.state = {banner: ['动作射击', '角色扮演', '策略运营'],productList: ['古墓丽影','镜之边缘','神秘海域','奥里给']}}render() {const { banner, productList } = this.state;return (<div><h2>Main</h2><Banner banner={banner} /><ProductList title="商品列表" productList={productList}/></div>)}
}
然后子组件在constructor
中使用super(props)
继承父类的props
属性,并把props
这个属性设置为传进来的值。
当然啊,如果不写constructor,也能自动接收到props,这是一个小细节。
class ProductList extends Component {constructor(props) {console.log(props);super(props);}render() {console.log(this.props)const { title, productList } = this.props;return (<div><div>{title}</div><ul>{productList.map(item => {return <li key={item}>{item}</li>})}</ul></div>)}
}
接下来我们就可以队商品列表和标题进行展示:
2.props接收数据类型限制和默认值
我们以Main
组件和ProductList
组件为例,将Main中的数据传给ProductList
class Main extends Component {constructor() {super();this.state = {productList: ['古墓丽影','镜之边缘','神秘海域','奥里给']}}render() {const { banner, productList } = this.state;return (<div><h2>Main</h2><ProductList age={18} title="商品列表" productList={productList}/><ProductList age={10}/></div>)}
}
接下来我们就可以在ProductList
组件中对接收的数据进行类型和默认值的设置:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class ProductList extends Component {constructor(props) {console.log(props);super(props);}render() {console.log(this.props);const { age,title, productList } = this.props;return (<div><h3>ProductList</h3><div>{age}</div><div>{title}</div><ul>{productList.map(item => {return <li key={item}>{item}</li>})}</ul></div>)}
}
//props接收数据类型的限定
ProductList.propTypes = {title: PropTypes.string, age: PropTypes.number.isRequired, //必须是数字类型,必须有productList: PropTypes.array,
}//props接收数据的默认值
ProductList.defaultProps = {title: '我的网页的干活',productList: [],
}
如上,首先引入PropTypes
import PropTypes from 'prop-types';
然后在类组件名字后面设置属性propTypes
。
默认值则设置属性defaultProps
。
其他细节可以翻看官方文档:props默认值大全
有些新东西比如我们现在可以通过static关键字直接在组件中写:
class Greeting extends React.Component {static defaultProps = {name: 'zzy'}render() {return (<div>Hello, {this.props.name}</div>)}
}
3.子传父用函数
这里的方法和vue中类似(vue还可以用组件自定义事件)
1、在父组件中通过属性给子组件传递一个回调
class App extends React.Component {getData(data) {console.log(data);}render() {return (<div><Son getSonData={(data) => this.getData(data)}/></div>)}
}
2、子组件可以调用父组件传的函数,并把组件数据作为参数传递过去,然后父组件就能拿到子组件的数据并进行后续操作。
class Son extends Component {constructor(props) {super(props);this.state = {sonData: '我是子组件数据'}}sendData() {//调用父组件传的函数并把子组件数据作为参数传过去this.props.getSonData(this.state.sonData);}render() {return (<div><h2>子组件</h2><button onClick={this.sendData.bind(this)}>点击把子组件数据传给父组件</button></div>)}
}
4.案例练习
给我实现下面这个效果:
这里我们把上面的导航栏封装成组件Navigate
,整体的思路如下:
1、父组件存放数据,先传给子组件一份
2、子组件接收数据并遍历展示
3、子组件添加按钮,动态显示类名active(原理就是通过点击事件修改currentIndex)
4、父组件给子组件一个回调,子组件动态显示类名后,把当前index传给父组件
5、父组件接收index并存起来,然后在下面展示对应的数据。
class App extends React.Component {constructor() {super();this.state = {navList: ['新款', '精选', '流行'],contentIndex: 0,}}getContent(index) {this.setState({contentIndex: index})}render() {let { navList, index } = this.state;return (<div><Navigation navList={navList} getContent={(index) => this.getContent(index)} /><h2>{navList[contentIndex]}</h2></div>)}
}
export class Navigate extends Component {constructor(props) {super(props);this.state = {currentIndex: 0,}}changeIndex(index) {this.setState({currentIndex: index})this.props.getContent(index);}render() {let { currentIndex } = this.state;let { navList } = this.propsreturn (<div className='nav'>{navList.map((nav, index) => {return (<divkey={nav}className={`title ${currentIndex === index ? 'active' : ''}`}onClick={() => this.changeIndex(index)}>{nav}</div>)})}</div>)}
}
备注:react中使用scss:npm add node-sass@npm:dart-sass
// 安装scss:npm add node-sass@npm:dart-sass
.nav {border: 2px solid black;display: flex;justify-content: space-around;.title {padding: 10px;&.active {color: red;border-bottom: 3px solid red;}}
}
六、React插槽效果
插槽也是父子通信的一种方式
1.通过props.children传递
我们在父组件中的子组件标签内部写几个div:
父组件App
render() {return (<div><Navigation><div className="left">左边</div><div className="middle">中间</div><div className="right">右边</div></Navigation></div>)}
那么子组件中就可以通过this.props.children
读取到我们写的这些div,如果写多个,那么children是一个数组
,如果写一个,那么children就是一个react元素
(当然啊,我们可以通过propType限制children的类型是数组还是react元素)。
子组件
export class Navigation extends Component {render() {//props中的children可以接收到子组件插槽中的react元素let {children} = this.props;return (<div className='box'>{children}</div>)}
}
这样的话,我们就可以拿着这些东西去子组件展示
2.通过props直接传递
上面这种用children接收的方式有个问题,就是接到父组件的react元素默认是按照子组件书写顺序传入children数组的,这样通过索引去写可能会有展示的顺序问题。,而且比较麻烦
render() {//props中的children可以接收到子组件插槽中的react元素let {children} = this.props;console.log(children)return (<div className='box'><div>{children[0]}</div><div>{children[1]}</div><div>{children[2]}</div></div>)}
比第一种更好的方式,就是我们在父组件中的子组件标签上直接添加属性,传入相应的react元素,子组件就可以通过props直接读取,直接用,非常奈斯
父组件
render() {const left = <div className="left">左边</div>;const middle = <div className="middle">中间</div>;const right = <div className="right">右边</div>;return (<div>{/* 2.第二种方式:直接通过props传react元素 */}<Navigation left={left} middle={middle} right={right}/></div>)}
子组件可以根据属性名随意切换顺序,不用去通过索引找元素
子组件
render() {//props中的children可以接收到子组件插槽中的react元素let {children,left,middle,right} = this.props;console.log(children)return (<div className='box'>{left}{right}{middle}</div>)}
3.作用域插槽
本质上还是父给子传个函数,然后子去调用并把当前的数据传给父组件,父组件根据数据的类型,返回不同的节点,这里就不写了。
七、祖孙及更深层次的通信
1.{…props}解构
使用{...props}
这种react官方提供的解构语法,可以直接把数据传下去,举个例子:
父组件export class App extends Component {constructor() {super();this.state = {person: { name: 'zzy', age: 18 }}}render() {let { person } = this.state;return (<div>{/* 1.第一种传递方式,繁琐 */}<Son name={person.name} age={person.age}/>{/* 2.第二种传递方式:直接解构 */}<Son {...person}/></div>)}
}
儿子
export class Son extends Component {render() {return (<div>{/* 2.传过来的props也是一个对象,直接结构继续往下传 */}<GrandSon {...this.props} /></div>)}
}
孙子
export class GrandSon extends Component {render() {return (<div><GGrandSon {...this.props}/></div>)}
}
曾孙可以直接拿到数据直接用
export class GGrandSon extends Component {render() {let {name, age} = this.props;return (<div><h2>我拿到了数据</h2><div>{name}-{age}</div></div>)}
}
2.Context的使用(类组件)
使用Context可以直接把数据给任意一层组件:
使用步骤:
1、使用React.createContext()
定义一个context
2、父组件引入一下
import myContext from './context'
在子组件外边包一个标签(也可以在孙子组件包,可以理解为给谁传就给谁包,如果儿子组件,那么孙子组件也可以用步骤3的方法获取数据,曾孙也可以),名字是刚才定义的名字.Provider
,然后加上value
属性,属性值就是要传的值。
{/* 3.第三种传递方式:context */}
<myContext.Provider value={{name:'ht', age:'10'}}><Son/>
</myContext.Provider>
3、子组件或孙子组件通过添加contextType
属性为可以把数据添加到this.context
上(说的官方点,就是订阅我们这个myContext):
import React, { Component } from 'react';
import GrandSon from './GrandSon';
import myContext from '../context'
export class Son extends Component {render() {console.log('Son',this.context);return (<div>{this.context.name}<GrandSon /></div>)}
}Son.contextType = myContext; //3.添加contextType
3.Context的使用(函数组件)
对于函数组件,我们需要这样来做:
相关文章:

React(三):脚手架、组件化、生命周期、父子组件通信、插槽、Context
React(三)一、脚手架安装和创建1.安装脚手架2.创建脚手架3.看看脚手架目录4.运行脚手架二、脚手架下从0开始写代码三、组件化1.类组件2.函数组件四、React的生命周期1.认识生命周期2.图解生命周期(1)Constructor(2&…...
[教程]使用 Git 克隆指定分支
Git 是我们开发过程中经常使用到的版本管理工具,在平常情况下我们从远程克隆的时候会将整个库克隆下来,这会包括整个版本库的历史提交记录和远程库里的所有分支。但在一些情况下,比如我们并不需要查看历史提交记录而只是希望能够获取到最新的代码&#x…...

Redis实现服务注册与服务发现源码阅读(Go语言)
Redis实现服务注册与服务发现源码阅读 背景 近期在看开源项目CloudWeGo中看到目前GoLang微服务框架Hertz中支持通过Redis实现服务注册与服务发现功能。便想着阅读下源码 源码阅读 gut clone了hertz-contrib后看到在一级目录下有目前各种主流的服务注册与发现的实现方案。为…...

论文复现-3
模型构建中的运算 数据集是CONLL03 这个数据集共有4种实体类型,所以,在做实体描述的embedding时,得到的语义表示的Tensor大小为 : 4*max_len, 具体指的是: type_input_ids: torch.LongTensor None, type_attention_m…...
667知识点 | 经过三年实战检验的667知识清单
文章目录 前言第一章 信息与信息资源第二章 信息社会第三章 信息交流第四章 信息技术第五章 信息组织第六章 信息管理活动第七章 信息资源人文管理第八章 信息资源经济管理第九章 信息资源系统管理第十章 信息资源管理专门化前言 参考书目:《信息管理导论(第三版)》党跃武推…...

后端快速上手前端三剑客 HtmlCSSJavaScript
文章目录前言HTML1.基础标签2.多媒体标签:3.表格&列表&布局4.表单CSS1.简介2.导入方式3.选择器JavaScript1.简介2.引入方式3.基本语法4.对象(1) 基本对象(2) BOM对象(3) DOM对象5.事件前言 结构:HTML 表现:CSS 行为:Java…...

Cdiscount、Allegro如何利用测评补单自养号提升店铺权重和流量
Allegro成立于 1999 年是在波兰最受欢迎的电商平台,75%的波兰人都知道该网站,Allegro的品牌认知度在波兰高达98%。Allegro平台卖家的数量目前还是比较少的约为13万,最重要的就是中国卖家占比少,所以竞争也比较低,像是美…...

第16天-性能压测:压力测试,性能监控,优化QPS,Nginx动静分离
1.性能监控 1.1.JVM架构 运行时数据区: 方法区:最重要的内存区域,多线程共享,保存了类的信息(名称、成员、接口、父类),反射机制是重要的组成部分,动态进行类操作的实现;…...
【python 基础篇 十一】python的函数-------函数的偏函数 高阶函数 返回函数 匿名函数 闭包
目录1.偏函数2.高阶函数3.返回函数4.匿名函数5.闭包1.偏函数 概念 当我们写一个参数比较多的函数时,如果有些参数,大部分场景下都是某一个固定值,那么为了简化使用,就可以创建一个新函数,指定我们要使用的函数的某个…...

妇女节到了,祝福所有女神 Happy Women‘s Day!
在每年3月8日人们庆祝妇女节 Womens Day is cllebrated on March 8 every year.国际妇女节(IWD),中国内地称“三八”国际劳动妇女节或国际劳动妇女节。是在每年的3月8日为庆祝妇女在经济、政治和社会等领域作出的重要贡献和取得的…...

etcd集群通过 Leader 写入数据,为什么K8s HA集群中讲每个 kube-apiserver 只和本机的 ETCD 通信
写在前面 对这个我不太明白,所有在 stackOverflow 的请教了大佬这里分享给小伙伴理解不足小伙伴帮忙指正 对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整…...

HTML 表单
HTML 表单和输入 HTML 表单用于收集不同类型的用户输入。 在线实例 创建文本字段 (Text field) 本例演示如何在 HTML 页面创建文本域。用户可以在文本域中写入文本。 创建密码字段 本例演示如何创建 HTML 的密码域。 (在本页底端可以找到更多实例。) …...

HTML、CSS学习笔记5(移动端基础知识、Flex布局)
一、移动端基础知识 1.PC端和移动端区别 移动端:手机版网页,手机屏幕小,网页宽度多数为100%,没有版心 PC端:电脑版网页,屏幕大,网页固定版心 PC端和移动端不是同一个网页 2.如何在电脑里面…...

【Java学习笔记】2.Java 开发环境配置
Java 开发环境配置 在本章节中我们将为大家介绍如何搭建Java开发环境。 window系统安装java 下载JDK 首先我们需要下载 java 开发工具包 JDK,下载地址:https://www.oracle.com/java/technologies/downloads/,在下载页面中根据自己的系统选…...

MyBatis——进阶操作(2)
标签 if标签 当提交的表单中有些为非必填项,用户并没有上传这些属性的值,那么程序可以上传NUll,也可以用if标签判断用户有没有上传这个值 <if test"参数!null">操作 </if>其中test中填写一条语句,如果得…...
循环结构
循环结构循环结构一、课前问答二、while循环三、do-while循环四、for循环五、流程控制5.1 break5.2 continue循环结构 一、课前问答 1、switch支持的数据类型。 2、switch中break的作用。 3、多重if如果多个条件都成立,执行方式。 二、while循环 语法: …...

漫谈数据库表设计及索引设计
一.数据库表设计 在数据库表设计上有个很重要的设计准则,称为范式设计。 什么是范式设计? 范式来自英文Normal Form,简称NF。MySQL是关系型数据库,但是要想设计—个好的关系,必须使关系满足一定的约束条件,…...

【JavaWeb】CSS基础知识:引入方式 + 选择器
CSS引入 CSS的引入有三种,三种的优缺点各不相同。 行内样式表 <!-- 行内样式表 --><!-- 相当于标签的一个属性 --><!-- 只对当前标签生效 --><!-- 优先级较高,会覆盖其他样式 --><p style"color: blue;">这是…...

02-前端-javaScript
文章目录JavaScript1,JavaScript简介2,JavaScript引入方式2.1 内部脚本2.2 外部脚本3,JavaScript基础语法3.1 书写语法3.2 输出语句3.3 变量3.3.1 全局变量var3.3.2 局部变量let3.3.3 常量const3.4 数据类型3.5 运算符3.5.1 \和区别 ▲3.5.2 …...
对链表学习的总结一
一,单链表结构定义 C/C++ 数组:一组具有相同类型数据的集合。结构体:不同类型数据的集合。 // Definition for singly-linked list. struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...