当前位置: 首页 > news >正文

React学习01 jsx、组件与组件的三大属性

文章目录

  • jsx的介绍与语法
      • 1.真实DOM和虚拟DOM
      • 2.jsx语法
  • 模块与模块化,组件与组件化
      • 模块与模块化
      • 组件与组件化
  • React组件
      • React事件绑定
      • 函数式组件
      • 类式组件
      • 组件属性state
      • 组件属性props
      • 组件属性ref

尚硅谷react教程+官方文档学习记录笔记01

jsx的介绍与语法

1.真实DOM和虚拟DOM

虚拟DOM本质是一般对象(Object对象),虚拟DOM的附带属性比真实DOM少,更轻量,虚拟DOM最终会被React转换成真实DOM显示在页面上。

<body><div id="h1">真实DOM</div><!-- ....省略引入react有关js文件,示范虚拟DOM渲染过程--><script type="text/babel">const vdom = <h1> Hello JS <h1/>;  // 虚拟DOMReactDOM.render(vdom,document.getElementById('h1'));  // 将虚拟DOM渲染到页面</script>
</body>

2.jsx语法

jsx语法是react定义的js+XML的语法,本质是React.creatElement(component,props,…children)的语法糖,用来简化和创建虚拟DOM。

// babel转译jsx成React.createElement()函数调用
const element = (<h1 className="greeting">Hello, world!</h1>
);
const element = React.createElement('h1',{className: 'greeting'},'Hello, world!'
);   // 两段代码等效

语法规则一:定义虚拟DOM变量,赋值不写引号

// 例子 创建一个h1标签的虚拟DOM
var element = <h1> Hello JS </h1>    // 最终产生一个JS对象// 创建嵌套标签
var element = (<h1><span> Hello JS </span></h1>)   // ()表示这一段为一个整体

语法规则二:标签中需要混入js表达式时使用{},表达式为可以接在=后的(let x = 表达式)

const data = "Hello JS";
var element = (<h1><span> {data} </span>  <span> {data.toLowerCase()} </span>  </h1>) 
// 使用jsx动态显示列表,页面显示一个列表,有a,b,c三个项,每个li标签必须有唯一的key值,这里为数组的下标
const data = [ 'a','b','c'];
const element = (<div><ul>{data.map((item,index)=>{return <li key ={index}< {item} </li>})}  // 这里的花括号里面是一个表达式</ul></div>
)

语法规则三:样式的类名使用className,内联样式使用style={{key:value}}。

var element1 = <h1 className="title"> Hello JS </h1> 
var element2 = <h1 style={{color:'white', fontSize:'20px'}}> Hello JS </h1>   // 类似font-size由多个词连接的属性改为小驼峰写法

语法规则四:虚拟DOM只能有一个根标签

var h1 = (<h1><span> {data} </span>  <span> {data.toLowerCase()} </span>  </h1>)    // h1为根标签var span = (<span> {data} </span>  <span> {data.toLowerCase()} </span>  )   // 错误,有两个根标签span

语法规则五:标签必须闭合,单标签以“/”结尾或者使用闭合标签

<input />
<input ></input>

语法规则六:标签的首字母规范:
1)以小写字母开头,则转换为html同名标签,若html无对应标签,报错;
2)以大写字母开头,react渲染该组件,若组件未定义,报错;
语法规则七:使用{/* 内容 */}在jsx内写注释。应避免在jsx结构内写注释

var element = (<div> {/* <h1>这是注释掉的标签</h1> */}<h1>这是未注释标签</h1></div> )

模块与模块化,组件与组件化

模块与模块化

模块:提供特定js功能的程序,一般指一个js文件;将代码拆成模块可以简化js,提高js运行效率;
模块化:应用的js都以模块编写

组件与组件化

组件:实现局部功能效果代码的资源集合,包含html,css,js,image,video等,考虑复用性,简化项目编码,提高运行效率;
组件化:应用以多组件的方式实现

React组件

在Chorme里导入ReactDevTool插件;

React事件绑定

react把js原生事件onXXX方法重写了,变成小驼峰写法,比如onclick方法变为onClick方法,使用时需要注意。函数调用时使用{}包含函数名。

<button onclick="activateLasers()"></button>  // 原生写法
<button onClick={activateLasers}></button>  // react写法

函数式组件

定义一个函数,函数名首字母大写,返回虚拟DOM,调用react的render方法时,使用闭合标签<函数名/>作为第一个参数

// 函数组件
<body><div id="test"></div><!--引入react有关js文件--><script type="text/javascript" src="react.development.js"></script><script type="text/javascript" src="react-dom.development.js"></script><script type="text/javascript" src="babel.min.js"></script><script  type="text/babel">// 创建函数式组件function Demo(){return <h1> Hello JS <h1/>;}// 渲染页面。过程:React解析组件标签,寻找Demo组件,发现组件是函数Demo定义的,调用Demo函数,返回虚拟DOMReactDOM.render(<Demo/>,document.getElementById('test'));  </script>
</body>

类式组件

定义一个类,继承React.Component类,无变量需要传递获取,不写supper方法,必须写render方法,返回虚拟DOM

// 类组件
<body><div id="test"></div><!--....省略引入react有关js文件--><script  type="text/babel">
// 创建类式组件
class Welcome extends React.Component {render() {return <h1>Hello</h1>;}
}// 渲染页面。过程:React解析组件标签,寻找Welcome组件,发现组件是类Welcome定义的,然后new一个Welcome实例对象,通过Welcome实例对象调用Welcome类里的render方法,返回虚拟DOMReactDOM.render(<Welcome/>,document.getElementById('test'));  </script>
</body>

简单组件(h函数组件)与复杂组件(类组件)区别在于有无状态State

组件属性state

状态(state)驱动页面。
类组件对象实例自带state属性,值为null。当需要使用state取值时,借助构造器初始化state为对象,将需要的变量挂在state对象上。

// 初始化并获取state
<body><div id="test"></div><!--....省略引入react有关js文件--><script  type="text/babel">
class Weather extends React.Component {// 定义构造器constructor(props){super(props);this.state = {isHot:false}  // 借助构造器初始化state}render() {return <h1>天气{this.state.isHot ? '热' : '凉'}</h1>;  // 获取state}
}ReactDOM.render(<Weather/>,document.getElementById('test'));  </script>
</body>
// 实现点击事件
class Weather extends React.Component {constructor(props){super(props);this.state = {isHot:false};this.changeWeather = this.changeWeather.bind(this); // 3. bind方法返回一个新函数,绑定在参数this上;这里bind(this)绑定了类的实例对象,这一行右边表示将类的changeWeather方法绑定在实例对象上,左边将绑定的函数取名为changeWeather}render() {return <h1 onClick={this.changeWeather}>天气{this.state.isHot ? '热' : '凉'}</h1>;   // 2.添加点击事件,这里相当于把类方法changeWeather作为onClick的回调,所以当用户点击时,this不是实例对象,且严格模式不能指向window,所以为undefined}// 点击事件changeWeather(){console.log(this);  // 1.类中的方法默认开启局部严格模式,非对象实例调用时,this指向undefined}
}
// 实现点击事件,理解以上注释部分
class Weather extends React.Component {constructor(props){super(props);this.state = {isHot:false};this.change = this.changeWeather.bind(this); }render() {return <h1 onClick={this.change}>天气{this.state.isHot ? '热' : '凉'}</h1>;  }// 点击事件changeWeather(){console.log(this);  }
}

state不能直接更改,更新要借助api setState()方法。

 // 点击事件里更改state里的变量 -- 直接更改changeWeather(){const isHot = this.state.isHot;   // 获取原来的isHot值this.state.isHot = !isHot;   // 点击后,借助开发插件可以看到this.state.isHot值没有变化,页面也无变化,react不允许直接改变状态}// 点击事件里更改state里的变量 -- 借助setState()方法changeWeather(){const i = this.state.isHot;  // 获取原来的isHot值this.setState({isHot:!i}); // 点击后,借助开发插件可以看到this.state.isHot值发生变化,页面也随state改变而改变}

setState方法起到的是一个合并的动作。

// 原state
state = {a:1,b:2,c:0}
// 使用setState()更新
this.setState({a:99});
// 更新后的state为
state = {a:99,b:2,c:0}

精简state写法,避免有多属性和多方法需要绑定。在类组件的类里使用属性名+赋值语句+值/函数。赋值的函数定义必须使用箭头函数。

class Weather extends React.Component {state = {isHot:false} // 往实例对象上挂一个state属性,值为一个对象,里面有isHot属性render() {return <h1 onClick={this.changeWeather}>天气{this.state.isHot ? '热' : '凉'}</h1>;  }changeWeather = ()=>{const i = this.state.isHot;   this.setState({isHot:!i});  } // 往实例对象上挂一个changeWeather属性,值为一个方法,方法里更新state。为什么使用箭头函数不使用function定义?因为箭头函数没有自己的this,箭头函数的this指向上下文的this,也就是实例对象
}

总结
1.state是对象,包含一个或多个key-value的组合,不能直接修改更新。
2.通过setState()方法更新state,从而从新渲染页面。
3.render()方法中的this指向的也是类组件的实例对象。
4.组件自定义方法的this为undefined时,在构造器里使用bind方法或使用赋值语句箭头函数改变this。
5.适用于用户数据交互渲染页面。

组件属性props

类组件对象实例自带props属性,值为{}。在ReactDOM.render方法内使用key="value"的方式传参,jsx内使用this.props.属性的方式接收。

// props的基本使用
class Person extends React.Component{     render(){return (<ul><li>name:{this.props.name}</li><li>sex:{this.props.sex}</li><li>age{this.props.age}</li></ul>)}}
ReactDOM.render(<Person name="tom" age="18" sex="男"/>,document.getElementById('test')); // 这里传递的age为字符串
ReactDOM.render(<Person name="tom" age={18} sex="男"/>,document.getElementById('test')); // 这里传递的age为Number

传递多个props属性时,使用{}+扩展运算符“…”

// 传递多个props属性
class Person extends React.Component{     render(){return (<ul><li>name:{this.props.name}</li><li>sex:{this.props.sex}</li><li>age{this.props.age}</li></ul>)}}// 定义变量,包含需要的属性
const p = {name:"tom",age:"18",sex:"男"};
// 传递时使用{}
ReactDOM.render(<Person {...p}/>,document.getElementById('test'));

对props属性做限制,如参数类型,默认值,必要性

// 写法1--在类的外部
// 对类组件定义一个propTypes属性,属性内规定了props各个属性的类型
类名.propTypes = {属性1: PropTypes.string.isRequired,  // 使用isRequired标定为必要字段属性2: PropTypes.number
}
// 对类组件定义一个defaultProps属性,属性内规定了props内各个属性的默认值
类名.defaultProps = {属性1:'默认值',属性2:'默认值'
}// 写法2--在类的内部
class 类名{static propTypes = {属性1: PropTypes.string.isRequired,  属性2: PropTypes.number}static defaultProps = {属性1:'默认值',属性2:'默认值'}// ...state,render等
}
// ... 增加一个引入文件,以使用对标签属性增加限制的方法
<script type="text/javascript" src="prop-types.js"></script>
<script type="text/babel">
class Person extends React.Component{     render(){return (<ul><li>name:{this.props.name}</li><li>sex:{this.props.sex}</li><li>age{this.props.age}</li></ul>)}}
// 对标签属性进行类型和必要性限制
Person.propTypes = {name: PropTypes.string.isRequired,age:PropTypes.number
}
// 对标签属性指定默认值
Person.defaultProps = {sex:'未知'
}
const p = {name:"tom",age:"18",sex:"男"};
ReactDOM.render(<Person {...p}/>,document.getElementById('test'));
</script>

对类组件传递方法

// 写法--在类的外部
Person.propTypes = {speak: PropTypes.func
}
function speak(){console.log('say something')
}
ReactDOM.render(<Person speak={speak}/>,document.getElementById('test'))

函数式组件使用props,组件三大属性中值由props可以在函数式组件使用。

function Person(props){return (<ul><li>name:{props.name}</li><li>sex:{props.sex}</li><li>age{props.age}</li></ul>)
}
Person.propTypes = {name: PropTypes.string.isRequired,age:PropTypes.number
}
Person.defaultProps = {sex:'未知'
}
ReactDOM.render(<Person  name="tom" age={18} sex="男"/>,document.getElementById('test'))

总结
1.props属性只读,使用this.props.属性=值会报错。
2.组件标签的所有属性都保存在props中,通过标签属性从组件外向组件内传递变化的数据,组件内不要修改props数据。
3.适用于父传子,组件间通信。

组件属性ref

类组件对象实例自带refs属性,值为{}。类似原生html标签的id属性。

<标签 ref="属性名"></标签>  // 在标签内定义
this.refs.属性名   // 使用
// refs基本使用
class Demo extends react.Component{showData = ()=>{console.log(this.refs); // {input1:input,button1:button,input2:input} input1是input标签的ref值,冒号后的input表示的是ref为input1的这一个input标签节点console.log(this.refs.input1); // <input type="text" placeholder=""/>}render(){return (<div><input ref="input1" type="text" placeholder="点击按钮"/><button ref="button1" onClick="{this.showData}">点击提示左侧数据</button><input ref="input2" type="text" placeholder=""/></div>)}
}
ReactDOM.render(<Demo/>,document.getElementById('test'));

以上为refs的字符串写法,ref属性都为字符串类型,会有效率问题。因此有了回调函数形式的ref。

<标签 ref={箭头函数}></标签>  // 在标签内定义,在创建节点时自动调用箭头函数
<标签 ref={(a)=>{this.属性名=a}}></标签>  // 在标签内定义,指定ref属性名
this.属性名   // 使用,因为直接挂在了实例对象上,所以可以直接使用this
// refs回调函数形式,使用内联函数
class Demo extends react.Component{showData = ()=>{console.log(this.input2.value)}render(){return (<div><input ref={(a)=>{console.log(a)}} type="text" placeholder="点击按钮"/>  // 打印<input type="text" placeholder="点击按钮"/><input ref={(a)=>{this.input2=a}} type="text" placeholder=""/> // 获取当前所在的节点(a,也就是input标签),将这个节点挂在组件实例对象上,并命名为input2<button ref="button1" onClick="{this.showData}">点击提示左侧数据</button></div> )}
}
ReactDOM.render(<Demo/>,document.getElementById('test'));

以上是使用内联函数的形式定义ref回调函数,内联函数在组件更新的时候会被执行两次,第一次传入参数null,第二次才传入DOM元素。因为每次调用render方法进行渲染时,都会创建一个新的函数实例,React会清空旧的ref然后设置一个新的,当旧的被清空,无法找到当前节点,所以第一次传入null。

// refs回调函数形式,使用内联函数,组件更新二次执行回调函数问题
class Demo extends react.Component{state = {isHot:'hot'}showData = ()=>{alert(this.input2.value)}showWeather = ()->{const isHot = this.state.isHot;this.setState({isHot:!isHot});}render(){return (<div><input ref={(a)=>{this.input2=a;console.log(a)}} type="text" placeholder=""/> <button ref="button1" onClick="{this.showData}">点击提示左侧数据</button>// 点击提示数据按钮,内联函数调用一次,打印<input  type="text" placeholder=""/><button  onClick="{this.showWeather}">点击提示天气</button>// 点击显示天气按钮,内联函数调用两次,第一次打印null第二次打印<input  type="text" placeholder=""/></div> )}
}
ReactDOM.render(<Demo/>,document.getElementById('test'));

下面类绑定式的ref写法可以避免调用两次的情况,但使用内联函数调用两次的影响无关紧要,可继续使用。

函数名=(a)=>{this.属性名=a}  // 在类组件内定义函数
<标签 ref=this.函数名></标签>  // 在标签内定义
// refs回调函数形式,使用类绑定的形式,解决组件更新时二次执行回调函数问题
class Demo extends react.Component{state = {isHot:'hot'}showData = ()=>{alert(this.input2.value)}showWeather = ()->{const isHot = this.state.isHot;this.setState({isHot:!isHot});}showInput = (a)=>{this.input2=a;console.log(a)}render(){return (<div><input ref={this.showInput} type="text" placeholder=""/> <button ref="button1" onClick="{this.showData}">点击提示左侧数据</button>// 点击提示数据按钮,内联函数调用一次,打印<input  type="text" placeholder=""/><button  onClick="{this.showWeather}">点击提示天气</button>// 点击显示天气按钮,内联函数不会被频繁调用</div> )}
}
ReactDOM.render(<Demo/>,document.getElementById('test'));

React.createRef调用后返回一个容器,容器内存储被ref标识的一个节点,每个被ref标识的节点都有专属自己的容器。

// 在类组件内,挂在类组件的实例对象上
myRef = React.createRef();
// 在虚拟DOM中
<input ref={this.myRef} type="text" />
// React.createRef的基本使用
class Demo extends React.Component{myRef = React.createRef()myRef2 = React.createRef()showRef(){console.log(this.myRef); // {current:input}console.log(this.myRef.current); //<input type="text" />console.log(this.myRef.current.value); // 输入框输入的值}render(){return (<div><input ref={this.myRef} type="text" /><input ref={this.myRef2} type="text" /><button onClick={this.showRef}>点击</button></div>)}
}

相关文章:

React学习01 jsx、组件与组件的三大属性

文章目录 jsx的介绍与语法1.真实DOM和虚拟DOM2.jsx语法 模块与模块化&#xff0c;组件与组件化模块与模块化组件与组件化 React组件React事件绑定函数式组件类式组件组件属性state组件属性props组件属性ref 尚硅谷react教程官方文档学习记录笔记01 jsx的介绍与语法 1.真实DOM和…...

项目——超级马里奥——Day(3)

一、游戏开发思路&#xff1a; 1.Frame--->BackGround--->Obstacle---->BufferedImage&#xff0c;人物等 2.BackGround的构造函数&#xff1a; 只要记住窗口里边的每一个场景&#xff0c;只要游戏一开始就已经出现在屏幕里边的&#xff0c;都是在构造函数里边 3.绘…...

测试-BUG篇

文章目录 软件测试的生命周期BUGbug的概念描述bug的要素bug级别bug的生命周期 与开发产生争执怎么办&#xff08;高频考题&#xff09; 软件测试的生命周期 软件测试贯穿于软件的整个生命周期 BUG bug的概念 是指计算机程序中存在的一个错误(error)、缺陷(flaw)、疏忽(mista…...

vue2中 vue-count-to组件让数字从某个数字动态的显示到某个数字(后附vue3的用法)

1、首先安装 npm install vue-count-to2、使用 2.1、先导入组件 import countTo from ‘vue-count-to’2.2、注册组件 components: { countTo },2.3、使用组件 <countTo> <template><div class"home"><countTo class"count-to&qu…...

AI模型部署初认识

AI部署这个词儿大家肯定不陌生&#xff0c;可能有些小伙伴还不是很清楚这个是干嘛的&#xff0c;但总归是耳熟能详了。 近些年来&#xff0c;在深度学习算法已经足够卷卷卷之后&#xff0c;深度学习的另一个偏向于工程的方向–部署工业落地&#xff0c;才开始被谈论的多了起来…...

在线生成论文的网站有哪些?分享5款AI一键原创论文免费网站

一、千笔-AIPasspaper 千笔-AIPasspaper是一款备受推荐的AI写作助手&#xff0c;它集成了多种功能&#xff0c;包括论文大纲生成、内容填充、文献引用和查重修改等。这款工具基于最新的自然语言处理技术&#xff0c;能够帮助用户快速生成高质量的论文内容。 AI论文&#xff0…...

考研论坛平台|考研论坛小程序系统|基于java和微信小程序的考研论坛平台小程序设计与实现(源码+数据库+文档)

考研论坛平台小程序 目录 基于java和微信小程序的考研论坛平台小程序设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂…...

Pandas 时间序列处理

Pandas 时间序列处理 说明&#xff1a; 请回答以下问题&#xff0c;以展示您对 pandas 中时间序列处理的全面理解。请在适用时提供代码示例。 问题 1 如何将日期字符串列表 [2023-01-01, 2023-01-02, 2023-01-03] 转换为 pandas 的 DatetimeIndex&#xff1f; 问题 2 给定一…...

PCL 1.8.1 + VTK 1.8.0 + QT5.14.2+ VS2017 环境搭建

先看看效果: PCL 1.8.1下载安装: Tags PointCloudLibrary/pcl GitHub 安装完成后: 如果VTK想重新编译的,可以看我的这篇博客:...

微信小程序和抖音小程序的分享和广告接入代码

开发完成小程序或者小游戏之后&#xff0c;我们为什么要接入分享和广告视频功能&#xff0c;主要原因有以下几个方面。 微信小程序和抖音小程序接入分享和广告功能主要基于以下几个原因&#xff1a; 用户获取与增长&#xff1a;分享功能可以帮助用户将小程序内容传播给更多人&…...

中断系统的原理

一、介绍 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的。中断是指‌CPU在正常运行程序时&#xff0c;由于内部或外部事件的发生&#xff0c;导致CPU中断当前运行的程序&#xff0c;转而去执行其他程序的过程。‌ 中断可以是硬件产生的&#xff0c;也可以是…...

安装Rust

Rust 是一种系统级编程语言&#xff0c;旨在提供高性能和内存安全&#xff0c;同时避免常见的编程错误。 由 Mozilla Research 推出&#xff0c;Rust 自推出以来因其独特的设计理念和强大的功能而在开发者社区中迅速获得了广泛的关注和采用。 curl --proto ‘https’ --tlsv1.2…...

vite学习教程05、vite+vue2构建本地 SVG 图标

文章目录 前言一、构建本地SVG图标详细步骤1、安装开发依赖2、配置vite2.1、配置vite.config.js2.2、封装vite引入插件脚本 解决报错&#xff1a;can not find package fast-glob imported 二、实际应用应用1&#xff1a;未封装&#xff0c;直接vue应用应用2&#xff1a;封装vu…...

机器学习——自监督学习与无监督学习

# 机器学习中的自监督学习与无监督学习 在机器学习的世界中&#xff0c;监督学习、无监督学习和自监督学习都是重要的学习方法。本文将聚焦于自监督学习与无监督学习&#xff0c;探讨它们的原理、应用场景以及技术细节&#xff0c;并通过大量代码示例来揭示这些方法的内在工作…...

2003经典绝版100%仿盛大服务端火炬引擎原版

;中国游戏制作 本版本为中国游戏制作小组推出的第一个版本&#xff0c;有什么不完美的地方还请大家多多指教&#xff01;&#xff01;&#xff01; 与盛大逼真&#xff01;&#xff01;&#xff01; 本版本M2Server采用“梦幻风”以及“冰眼”M2Server修改器修改的 2004/1/…...

银河麒麟服务器:更新软件源

银河麒麟服务器&#xff1a;更新软件源 1、使用场景2、操作步骤3、注意事项 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 1、使用场景 当需要安装最新软件或修改软件源配置后&#xff0c;需更新软件源以获取最新软件包信息。 2、操作步…...

字节跳动收购Oladance耳机:强化音频技术,加速VR/AR生态布局

字节跳动收购Oladance耳机&#xff1a;加码VR/AR领域布局 近日&#xff0c;字节跳动宣布已完成对开放式耳机品牌Oladance的收购&#xff0c;实现了对该品牌的100%控股。这一收购标志着字节跳动在AI硬件领域的进一步扩展和深化&#xff0c;特别是对其VR/AR领域布局的重要加码。 …...

Android SystemUI组件(11)SystemUIVisibility解读

该系列文章总纲链接&#xff1a;专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节持续迭代之前章节思维导图&#xff0c;主要关注左侧最上方SystemUiVisibility解读部分即可。 本章节主要讲解SystemUiVisibility的概念及其相…...

JSON 全知全解:深入探索 JSON 的奥秘

目录 一、JSON 基础认知&#xff08;一&#xff09;JSON 的定义与历史&#xff08;二&#xff09;JSON 的语法规则&#xff08;三&#xff09;JSON 与 JS 对象的关系 二、JSON 在不同语言中的用法&#xff08;一&#xff09;JavaScript 中的 JSON 操作&#xff08;二&#xff0…...

CSS | 响应式布局之媒体查询(media-query)详解

media type(媒体类型)是CSS 2中的一个非常有用的属性&#xff0c;通过media type我们可以对不同的设备指定特定的样式&#xff0c;从而实现更丰富的界面。media query(媒体查询)是对media type的一种增强&#xff0c;是CSS 3的重要内容之一。随着移动互联网的发展&#xff0c;m…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

在Spring Boot中集成RabbitMQ的完整指南

前言 在现代微服务架构中&#xff0c;消息队列&#xff08;Message Queue&#xff09;是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件&#xff0c;支持多种消息协议&#xff0c;具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...

C# WPF 左右布局实现学习笔记(1)

开发流程视频&#xff1a; https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源码&#xff1a; GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF应用&#xff08;.NET Framework) 2.…...

篇章一 论坛系统——前置知识

目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构​编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...

timestamp时间戳转换工具

作为一名程序员&#xff0c;一款高效的 在线转换工具 &#xff08;在线时间戳转换 计算器 字节单位转换 json格式化&#xff09;必不可少&#xff01;https://jsons.top 排查问题时非常痛的点: 经常在秒级、毫秒级、字符串格式的时间单位来回转换&#xff0c;于是决定手撸一个…...

Docker 镜像上传到 AWS ECR:从构建到推送的全流程

一、在 EC2 实例中安装 Docker&#xff08;适用于 Amazon Linux 2&#xff09; 步骤 1&#xff1a;连接到 EC2 实例 ssh -i your-key.pem ec2-useryour-ec2-public-ip步骤 2&#xff1a;安装 Docker sudo yum update -y sudo amazon-linux-extras enable docker sudo yum in…...