react库的基础学习
React介绍
React.js是前端三大新框架:Angular.js、React.js、Vue.js之一,这三大新框架的很多理念是相同的,但是也有各自的特点。
React起源于Facebook的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。
React可以作为一个js库来使用,我们在页面上引用相关的js文件,就可以使用它来做一些页面效果。
React也可以将界面拆分成一个个的组件,通过组件来构建界面,然后用自动化工具来生成单页面(SPA - single page application)应用系统。
—脚手架
快速开始
首先通过将React作为一个js库来使用,来学习React的一些基本概念,在页面上引入已经下载好的三个js文件,就可以使用React了。
<script src="js/react.development.js"></script>
<script src="js/react-dom.development.js"></script>
<script src="js/babel.min.js"></script>
其中,前两个js文件是React的核心文件,第三个js文件是一个转换编译器,它能将ES6语法及jsx语法转换成可以在浏览器中运行的代码。
编写hello world程序
<div id="root"></div>
<script type="text/babel"> ReactDOM.render(<h1>Hello world!</h1>,document.getElementById('root'))
</script>
上面编写的,不是真正的JavaScript代码,因为上面是JavaScript代码和html的混合,所以它的类型需要写成“text/babel”,最终通过编译器编译成浏览器可以执行的js。
示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><!-- 以下js库负责编译es6语法和jsx语法,编译成浏览器可以识别的语法 --><script src="js/babel.min.js"></script>
</head>
<body><!-- react把生成的效果全部放到div里面 --><!-- 标签和js写一块 --><div id="root"></div><script type="text/babel">// 第一个参数jsx的对象 第二个参数是对象ReactDOM.render(<h1>hello world!</h1>,document.getElementById('root'))</script>
</body>
</html>
JSX语法
jsx语法是一种类似于html标签的语法,它的作用相当于是让我们在JavaScript代码中直接写html代码,但是jsx不完全是html,它是 JavaScrip 的一种扩展语法,它具有 JavaScript 的全部能力,我们还可在jsx代码中插入变量或者表达式,用jsx语法写出来的语句是一个对象,我们可以将它存为一个变量,这个变量作为ReactDOM对象的render方法的第一个参数。
let el = <h1>Hello world!</h1>;
ReactDOM.render(el,document.getElementById('root')
)
jsx的结构还可以写得更复杂,可以是嵌套结构,如果是嵌套结构,需要有唯一的一个外层标签。标签中如果是单个的标签,在结尾要加“/”,在jsx中可以通过“{}”插入变量,表达式或者函数调用。
<script type="text/babel">let iNum01 = 10;let sTr = 'abc123456';let ok = true;function fnRev(s){return s.split('').reverse().join('');} let el = (<div><h3>jsx语法</h3>{/* 插入变量及运算 */}<p>{ iNum01+5 }</p>{/* 插入表达式 */}<p>{ sTr.split('').reverse().join('') }</p>{/* 插入函数调用 */}<p>{ fnRev(sTr) }</p>{/* 插入三元运算表达式 */}<p>{ ok?'YES':'NO' }</p> </div>);ReactDOM.render(el,document.getElementById('root'))</script>
示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><!-- 以下js库负责编译es6语法和jsx语法,编译成浏览器可以识别的语法 --><script src="js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">let iNum01 = 10;let sTr = 'abcdefgh123456';let ok = false;let url = 'http://www.baidu.com';function fnRev(s){return s.split('').reverse().join('');}let el =(<div><h2>jsx语法</h2>{/* 插入变量及运算 */}<p>{ iNum01+5 }</p>{/*插入字符串*/}<p>{ sTr }</p>{/* 插入表达式 */}<p>{ sTr.split('').reverse().join('') }</p>{/* 插入函数调用 */}<p>{ fnRev(sTr) }</p>{/* 插入三元运算表达式 */}<p>{ ok?'YES':'NO' }</p></div>);ReactDOM.render(el,document.getElementById('root'));</script>
</body>
</html>
jsx中指定标签的属性值建议用双引号,不能不用引号,属性名建议用驼峰式,其中class属性需要写成className,属性值如果是可变的,也可以写成“{}”的形式,里面可以和上面写法一样。 标签如果是单个的,在结尾一定要加“/”
{/* 定义class */}
<p className="sty01">使用样式</p>
{/* 单个标签,结尾要加“/” */}
<img src={user.avatarUrl} />
示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><!-- 以下js库负责编译es6语法和jsx语法,编译成浏览器可以识别的语法 --><script src="js/babel.min.js"></script><style>.sty01{font-size: 30px;color: red;}</style>
</head>
<body><div id="root"></div><script type="text/babel">let url = 'http://www.baidu.com';let el =(<div><a href={url} className="sty01">这是一个链接</a></div>);ReactDOM.render(el,document.getElementById('root'));</script>
</body>
</html>
组件和属性(props)
组件可以理解成是一个组成页面的部件或者零件,每个部件都有自己完整的结构和功能,多个部件拼装在一起就可以组成一个页面,从组件的实现来看,组件最终是要返回一个jsx对象,不过它和jsx对象的区别是,它在jsx对象的基础上,还带有自己的方法和属性,能完成它自己的交互功能。 组件有两种定义方式:一种是函数式定义,一种是类定义。
函数式定义组件
通过函数来定义一个组件,组件名称首字母要大写,函数接收一个参数props,返回一个jsx对象。其中,name属性是在渲染组件时,通过定义属性传入进来的。
function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}
类方式定义组件
上面的组件可以通过下面ES6的类的方式定义,定义的类都要继承于React对象中的Component类,这个定义的组件和上面的功能是等效的。
class Welcome extends React.Component {render() {return <h1>Hello, {this.props.name}</h1>;}
}
组件渲染
组件渲染和jsx对象一样,我们可以通过ReactDOM.render()方法来渲染组件。
function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(element,document.getElementById('root')
);
组件组合
可以在一个组件内,拼装其他的组件,从而组合成一个更大的组件
function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}function App() {return (<div><Welcome name="Sara" /><Welcome name="Cahal" /><Welcome name="Edite" /></div>);
}ReactDOM.render(<App />,document.getElementById('root')
);
示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><!-- 以下js库负责编译es6语法和jsx语法,编译成浏览器可以识别的语法 --><script src="js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">class Welcome extends React.Component{render(){return(<h1>hello, {this.props.name}</h1>);}}//定义一个大的组件,组合上面的组件class WelcomeAll extends React.Component{render(){return (<div><Welcome name = "Sara"/><Welcome name = "Tom" /><Welcome name = "Rose" /></div>);}}//this.props = {name: "Sara"}===》<Welcome name = "Sara"/> 渲染小的组件// ReactDOM.render(<Welcome name = "Sara"/>,document.getElementById('root'));//渲染大的组件ReactDOM.render(<WelcomeAll />,document.getElementById('root'));</script>
</body>
</html>
绑定事件
React绑定事件和JavaScript中的行间事件类似,事件绑定是写在标签中的,但是,React事件是在原生事件的基础上做了封装,它的事件使用驼峰命名,而不是全部小写。事件需要传递一个函数作为事件处理程序,这个函数在哪里定义呢?我们可以通过类定义组件,将这个函数作为一个方法定义在组件中。
定义一个点击能弹出名称的组件:
class Helloname extends React.Component {fnHello(){alert('Hello,Tom');}render(){return (<input type="button" value="打招呼" onClick={this.fnHello} />)}
}
ReactDOM.render(<Helloname />, document.getElementById('root'));
如果想把这个组件定义成可以传递名称参数的,可以定义如下:
class Helloname extends React.Component {fnHello(){alert(this.props.name);}render(){return (<input type="button" value="打招呼" onClick={this.fnHello.bind(this)} />)}
}ReactDOM.render(<Helloname name="Tom" />, document.getElementById('root'));
需要注意的是,按钮在调用方法时,此时的this默认会指向这个按钮,所以在绑定事件时,需要绑定this,将this指向当前对象。
示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><!-- 以下js库负责编译es6语法和jsx语法,编译成浏览器可以识别的语法 --><script src="js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">class HelloTom extends React.Component{//定义click事件的处理方式fnHello(){alert("Hello,Tom!");}render(){return(<input type="button" value="打招呼" onClick={this.fnHello} />)}}//定义有参方法class HelloName extends React.Component{fnHello(){alert("Hello,"+this.props.name);}render(){return (//在事件调用方法时,如果方法里面使用了this,在方法中需要绑定this<input type="button" value="打招呼啊" onClick={this.fnHello.bind(this)}/>)}}//如果43行显示出来,则只会显示44行// ReactDOM.render(<HelloTom />, document.getElementById('root'));ReactDOM.render(<HelloName name = "Jack"/>,document.getElementById('root'));</script>
</body>
</html>
状态
组件如果需要定义默认属性呢?而且这个默认属性还是可变的呢?这个就是组件的状态属性了,状态属性默认名称是state,这个属性需要在组件定义时初始化,所以我们需要使用类的构造函数来对这个属性进行初始化。
定义一个点击按钮数字递增的
class Increase extends React.Component {constructor(props){super(props);this.state = {iNum:10};// 也可以在组件初始化时将方法绑定thisthis.fnAdd = this.fnAdd.bind(this);}fnAdd(){// 使用setState来改变state中的值this.setState(prevState=>({iNum:prevState.iNum+1}));}render(){return (<div><p>{ this.state.iNum }</p><input type="button" onClick={this.fnAdd} value="递增" /></div>);}
}ReactDOM.render(<Increase />,document.getElementById('root')
);
state注意点
1、不能直接修改state的值,应该用setState代替
// 下面写法是不会更新组件,是错误的
this.state.iNum = 11;// 应该写成setState的形式
this.setState({iNum: 11});
2、state的值可能是异步的,如果需要在state的值的基础上修改得到新的值,可以使用函数的形式,函数的参数中传递的第一个参数是state上一个状态的值,我们可以在这个值基础上修改,下面的prevState代表state上一个状态的值。
this.setState(prevState=>({iNum:prevState.iNum+1
}));
示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><!-- 以下js库负责编译es6语法和jsx语法,编译成浏览器可以识别的语法 --><script src="js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel"><div id="root"></div>class Increase extends React.Component{constructor(props) {super(props);this.state = {iNum:10};}// 要通过setState方法来改变state里面的值//setState里面可以传一个对象,也可以传一个函数,函数需要返回一个对象fnAdd(){//这样写也是可以的// this.state.iNum +=1;// this.setState({// iNum:11// })/* this.setState({//虽然可以这样写是可以的,但是不建议这样用iNum:this.state.iNum+1})*/// prevState 指的是state最新的值// this.setState(function(prevState){// return { iNum:prevState.iNum+1}// })//return 字典或者对象需要加()this.setState(prevState=>({iNum:prevState.iNum+1}))}render(){return (<div><p>{this.state.iNum}</p><input type="button" value="递增" onClick={this.fnAdd.bind(this)}/></div>)}}ReactDOM.render(<Increase />, document.getElementById('root'));</script>
</body>
</html>
选项卡案例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>.tab_con{width:500px;height:350px;margin:50px auto 0;}.tab_btns{height:50px;}.tab_btns input{width:100px;height:50px;background:#ddd;border:0px;/*去掉行间的高亮*/outline:none;}.tab_btns .active{background:gold;}.tab_cons{height:300px;background:gold;}.tab_cons div{height:300px;line-height:300px;text-align:center;display:none;font-size:30px;}.tab_cons .current{/*以块元素显示出来*/display:block;}</style><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><!-- 以下js库负责编译es6语法和jsx语法,编译成浏览器可以识别的语法 --><script src="js/babel.min.js"></script>
</head><body><div id="root"></div><script type="text/babel">class Tab extends React.Component{constructor(props) {super(props);this.state = {iNow:0}}fnChange(i){this.setState({iNow:i})}// 行内元素放在一行,就会去掉间距render(){return (<div className="tab_con"><div className="tab_btns">{/*<p>{this.state.iNow}</p>*/}<input type="button" value="按钮一" className={(this.state.iNow==0)?"active":''} onClick={this.fnChange.bind(this,0)}/><input type="button" value="按钮二" className={(this.state.iNow==1)?"active":''} onClick={this.fnChange.bind(this,1)}/><input type="button" value="按钮三" className={(this.state.iNow==2)?"active":''} onClick={this.fnChange.bind(this,2)} /></div><div className="tab_cons"><div className={(this.state.iNow==0)?"current":''}>按钮一对应的内容</div><div className={(this.state.iNow==1)?"current":''}>按钮二对应的内容</div><div className={(this.state.iNow==2)?"current":''}>按钮三对应的内容</div></div></div>);}}ReactDOM.render(<Tab />,document.getElementById("root"));</script>
</body>
</html>
列表渲染
如何拼装数组中的数据放入页面呢?可以将数组中的数据通过数组遍历渲染成一个jsx对象,在通过React渲染这个对象就可以了。
let aList = ['红海','复联3','碟中谍6','熊出没'];let el = aList.map((item,i)=><li key={i}>{ item }</li>
);ReactDOM.render(<ul>{el}</ul>, document.getElementById('root')
);
通过map方法遍历数组中的成员,map方法的第二个参数是数组中的索引值,在循环生成li结构时,需要给每个li加上一个key,这个key的值可以用数组中的成员索引值。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><!-- 以下js库负责编译es6语法和jsx语法,编译成浏览器可以识别的语法 --><script src="js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">let aList = ['红海','复联三','碟中谍6','熊出没'];let el = aList.map((item,i)=><li key={i}>{item}</li>);//第二种写法// let el = aList.map(function (item,i){// return <li key={i}>{item}</li>;// });ReactDOM.render(<ul>{el}</ul>,document.getElementById('root'));</script>
</body>
</html>
表单数据绑定—双向数据绑定
表单元件对应着数据,而且这些数据都是变化的,所以我们会将表单元件的数据对应于组件中的state属性值,让它们之间的值实现双向数据绑定的效果,要实现这个效果,需要在表单元件上绑定onchange事件,来将state中的值改变为表单元件中的值,同时也需要将表单的value属性值,设置为等于state中的属性值。
表单数据绑定示例:
class Myform extends React.Component {constructor(props){super(props);this.state = {uname:''};}// ev指的是系统自动产生的事件对象// ev.target指的是发生事件的元素fnNameInput(ev){this.setState({uname:ev.target.value})}render(){return(<form><p>用户的名称是:{ this.state.uname }</p><input type="text" value={this.state.uname} onChange={this.fnNameInput.bind(this)} /> </form>);}
}ReactDOM.render(<Myform />, document.getElementById('root')
);
示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><script src="js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">class Inputxt extends React.Component{constructor(props) {super(props);this.state = {iNum:11}}// ev指的是系统自动产生的事件对象// ev.target指的是发生事件的元素fnChange(ev){this.setState({iNum: ev.target.value})}render(){return (<div><p>{ this.state.iNum }</p><input type="text" value={ this.state.iNum } onChange={this.fnChange.bind(this)}/></div>);}}ReactDOM.render(<Inputxt />,document.getElementById('root'));</script>
</body>
</html>
todolist(计划列表)—案例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>todolist</title><style type="text/css">.list_con{width:600px;margin:50px auto 0;}.inputtxt{width:550px;height:30px;border:1px solid #ccc;padding:0px;text-indent:10px;}.inputbtn{width:40px;height:32px;padding:0px;border:1px solid #ccc;}.list{margin:0;padding:0;list-style:none;margin-top:20px;}.list li{height:40px;line-height:40px;border-bottom:1px solid #ccc;}.list li span{float:left;}.list li a{float:right;text-decoration:none;margin:0 10px;}</style><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><script src="js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">class Todolist extends React.Component{constructor(props) {super(props);this.state = {aList:['学习html','学习css','学习javascript','学习go语言'],sTodo:''}}//把事件的对象给evfnChange(ev){this.setState({sTodo:ev.target.value})}fnAdd(){// this.setState(function (prevState){// if (prevState.sTodo == ''){// alert("请输入内容!");// return;// }// })this.setState(prevState =>{// 判断是否为空if (prevState.sTodo == ''){alert("请输入内容!");return;}//sTodo 输入框赋值为空return {aList: [...prevState.aList,prevState.sTodo],sTodo:''}})}fnDel(i){this.setState(prevState =>{//复制一份let list = [...prevState.aList];list.splice(i,1);return {aList:list};})}fnUp(i){this.setState(prevState =>{if (i==0){alert('到顶了!');return;}//复制一份let list = [...prevState.aList];let nowItem = list[i];list.splice(i,1); //删除list[i]数据// console.log(list);list.splice(i-1,0,nowItem); //在list[i-1]处添加数据// console.log(list);return {aList:list};})}fnDown(i){this.setState(prevState =>{if (i== prevState.aList.length-1){alert('到底了!');return;}//复制一份let list = [...prevState.aList];let nowItem = list[i];list.splice(i,1); //删除list[i]数据// console.log(list);list.splice(i+1,0,nowItem); //在list[i+1]处添加数据// console.log(list);return {aList:list};})}render(){return (<div className="list_con"><h2>To do list</h2><input type="text" value={this.state.sTodo} id="txt1" className="inputtxt" onChange={this.fnChange.bind(this)}/><input type="button" value="增加" id="btn1" className="inputbtn" onClick= {this.fnAdd.bind(this)}/><ul id="list" className="list">{this.state.aList.map((item,i)=><li key={i}><span>{item}</span><a href="javascript:;"className="up" onClick={this.fnUp.bind(this,i)}> ↑ </a><a href="javascript:;"className="down" onClick={this.fnDown.bind(this,i)}> ↓ </a> <a href="javascript:;"className="del" onClick={this.fnDel.bind(this,i)}>删除</a></li>)}</ul></div>);}}ReactDOM.render(<Todolist />, document.getElementById('root'));</script>
</body>
</html>
生命周期方法
生命周期方法,指的是在组件初始化后,以及组件销毁时,会自动执行的两个方法,我们可以在初始化方法中执行获取数据的操作,在组件销毁方法中执行一些清除操作,比如清除定时器等操作。这两个方法分别是:componentDidMount 和 componentWillUnmount。
使用示例:
class Hello extends React.Component{constructor(props){super(props);this.state = {}}// 组件初始化时自动执行的方法 componentDidMount() {console.log('componentDidMount');}// 组件销毁时自动执行的方法componentWillUnmount(){console.log('componentWillUnmount'); }render(){return (<h1>Hello world!</h1>);}
}ReactDOM.render(<Hello />,document.getElementById('root'));setTimeout(() => {ReactDOM.render(<h1>切换组件</h1>,document.getElementById('root'));
}, 2000);
示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/react.development.js"></script><script src="js/react-dom.development.js"></script><script src="js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">class HelloWorld extends React.Component{componentDidMount(){console.log('componentDidMount');}componentWillUnmount(){console.log('componentWillUnmount');}render(){return (<h1>Hello World!</h1>)}}ReactDOM.render(<HelloWorld />, document.getElementById('root'));//组件销毁setTimeout(()=>{ReactDOM.render(<h1>Bye Bye!</h1>,document.getElementById('root'));},3000);</script>
</body>
</html>
数据交互
React没有集成ajax功能,要使用ajax功能,可以使用官方推荐的axios.js库来做ajax的交互。 axios库的下载地址:https://github.com/axios/axios/releases
axios使用方法
常用参数:
1、url 请求地址
2、method 请求方式,默认是’GET’,常用的还有’POST’
3、responsetype 设置返回的数据格式,常用的是’json’格式,也可以设置为’text’或者’html’
4、params 设置发送给服务器的数据
5、then 设置请求成功后的回调函数
6、catch 设置请求失败后的回调函数
axios完整写法:
axios({url: '/user/12345',method: 'get',responsetype:'json',params: {firstName: 'Fred',lastName: 'Flintstone'}
})
.then(function (response) {console.log(response);
})
.catch(function (error) {console.log(error);
});
axios请求的写法也写成get方式后post方式。
执行get请求
// 为给定 ID 的 user 创建请求
// then是请求成功时的响应,catch是请求失败时的响应
axios.get('/user?ID=12345')
.then(function (response) {console.log(response);
})
.catch(function (error) {console.log(error);
});// 可选地,上面的请求可以这样做
axios.get('/user', {params: {ID: 12345}
})
.then(function (response) {console.log(response);
})
.catch(function (error) {console.log(error);
});
执行post请求
axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'
})
.then(function (response) {console.log(response);
})
.catch(function (error) {console.log(error);
});
脚手架开发
脚手架开发指的是react提供了完整的自动化开发工具及规划好了开发一个应用的项目目录,这些工具是通过nodejs开发的,我们可以通过npm(nodejs包管理命令)来安装这些工具,同时可以通过这个工具生成一个应用的项目目录。
安装脚手架工具
脚手架工具是nodejs的一个包,安装这个工具之前需要先安装nodejs,然后在终端执行以下命令:
1、设置npm淘宝景象
npm config set registry https://registry.npm.taobao.org
2、安装
npm install -g create-react-app
生成应用项目目录
3、生成app
create-react-app my-app
4、启动
cd my-app
npm start
5、生成上线文件
npm run build
项目目录说明
以上是执行生成命令自动生成的项目目录,对应的文件夹作用如下:
目录一:src目录,主开发目录,里面包含所有项目的组件,开发组件都是基于此目录
目录二:public目录,项目入口文件目录,目录中的文件不用动
目录三:项目开发依赖包文件目录,项目安装的包都会自动安装在这个文件夹中
目录四:build目录,项目上线时,执行npm run build生成的目录,这里面是自动化工具生成的上线文件
安装axios模块
1、在终端的项目目录,执行如下命令
npm install axios
2、在模块文件中引入
import axios from 'axios';
相关文章:

react库的基础学习
React介绍 React.js是前端三大新框架:Angular.js、React.js、Vue.js之一,这三大新框架的很多理念是相同的,但是也有各自的特点。 React起源于Facebook的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满…...

FFmpeg 基础模块:容器相关的 API 操作
目录 AVFormat 模块 AVFormat 前处理部分 AVFormat 读写处理部分 小结 思考 FFmpeg 目录中包含了 FFmpeg 库代码目录、构建工程目录、自测子系统目录等,具体内容如下: 现在你知道 FFmpeg 的源代码目录中都包含了哪些内容,在之后使用 FFm…...

SpringMVC+统一表现层返回值+异常处理器
一、统一表现层返回值 根据我们不同的处理方法,返回的数据格式都会不同,例如添加只返回true|false,删除同理,而查询却返回数据。 Result类 为此我们封装一个result类来用于表现层的返回。 public class Result {//描述统一格式…...

2023年地理信息系统与遥感专业就业前景与升学高校排名选择
活动地址:毕业季进击的技术er 地理信息系统(GIS,Geographic Information System),又称“地理信息科学”(Geographic Information Science),是一种具有信息系统空间专业形式的数据管理…...
第五章:最新版零基础学习 PYTHON 教程—Python 字符串操作指南(第二节 - Python 字符串—Python 字符串 len()的语法)
Python len() 函数返回字符串的长度。 目录 Python len() 语法 Python len() 示例 示例 1:带有元组和字符串的 Len() 函数...

ubuntu22.04使用共享文件设置
从ubuntu20.04开始,设置共享文件就很麻烦 第一步: 安装samba: sudo apt install samba第二步; 创建一个共享文件夹 我以桌面Desktop为例子 第三步: 设置密码: sudo smbpasswd -a ygc第四步: sudo vim …...

pycharm配置python3.8版本专门用于undecteded_chromedriver测试
pycharm配置python3.8版本专门用于undecteded_chromedriver测试 作者:虚坏叔叔 博客:https://pay.xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 一、Pycharm及python环境的配置 1.安装python-3.8.7rc1-amd64.e…...

基于SpringBoot的民宿在线预定平台
目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 民宿信息管理 民宿资讯管理 民宿分类管理 用户注册 民宿信息 我的订单 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实…...

CTFHUB SSRF
目录 web351 编辑 web352 web353 web354 sudo.cc 代表 127 web355 host长度 web356 web357 DNS 重定向 web358 bypass web359 mysql ssrf web360 web351 POST查看 flag.php即可 web352 <?php error_reporting(0); highlight_file(__FILE__); $url$_…...

FreeRTOS入门教程(队列详细使用示例)
文章目录 前言一、队列基本使用二、如何分辨数据源三、传输大块数据总结 前言 上篇文章我们已经讲解了队列的概念和队列相关的API函数,那么本篇文章的话就开始带大家来学习使用队列。 一、队列基本使用 这个例子将会创建三个任务,其中两个任务用来发送…...

【Kafka专题】Kafka收发消息核心参数详解
目录 前置知识课程内容一、从基础的客户端说起(Java代码集成使用)1.1 消息发送者源码示例1.2 消息消费者源码示例1.3 客户端使用小总结 *二、从客户端属性来梳理客户端工作机制*2.1 消费者分组消费机制2.2 生产者拦截器机制2.3 消息序列化机制2.4 消息分…...
matlab 使用激光雷达检测、分类和跟踪车辆
目录 1、算法概述2、加载数据3、地平面分割4、语义分割5、聚类和边界盒拟合6、可视化设置7、循环遍历数据8、面向跟踪的包围盒9、 总结10、 支持功能11、 参考</...
代码随想录训练营二刷第四十八天 | 139.单词拆分 背包问题总结
代码随想录训练营二刷第四十八天 | 139.单词拆分 背包问题总结 一、139.单词拆分 题目链接:https://leetcode.cn/problems/word-break/ 思路:单词拼字符串,完全背包。定义dp[i],为true表示可以拆分为一或多个单词。可能会出现ab…...
【数据挖掘】2017年 Quiz 1-3 整理 带答案
目录 Quiz 1Quiz 2Quiz 3Quiz 1 Answer Problems 1-2 based on the following training set, where A , B , C A, B, C A,B,</...

吃鸡高手必备工具大揭秘!提高战斗力,分享干货,一站满足!
大家好!你是否想提高吃鸡游戏的战斗力,分享顶级的游戏作战干货,方便进行吃鸡作图和查询装备皮肤库存?是否也担心被骗,希望查询游戏账号是否在黑名单上,或者查询失信人和VAC封禁情况?在这段视频中…...

集群化环境前置准备
目录 部署 1. 配置多台Linux虚拟机 1.1 首先,关机当前CentOS系统虚拟机(可以使用root用户执行init 0来快速关 机) 1.2 新建文件夹 1.3 克隆 1.4 同样的操作克隆出:node2和node3 1.5 开启node1,修改主机名为node1&…...

nodejs开发环境搭建
Nodejs是一个开源的、跨平台JavaScript运行时环境,其使用V8引擎对JavaScript脚本执行解释,在前后端分离的应用架构设计中,其既能支持web页面服务应用的开发、也能支持后端接口服务应用的开发,类似于Java语言的J2EE运行时环境&…...

C语言qsort函数
排序qsort int int cmp(const void *a, const void *b) {return *(int *)a - *(int *)b;//先强转成int型,后解引用取值比较大小 }字符串数组 char a[] “hello world” //字符串数组,存放的是字符 int cmp(const void *a, const void *b) {return *(…...

如何使用 Hotshot 通过文字生成 GIF 动画
Hotshot 是一个基于人工智能的工具,可用于通过文字生成 GIF 动画。该工具使用最新的图像生成技术来创建逼真的动画,即使是复杂的文字描述也能做到。 hotshot访问地址 使用 Hotshot 生成 GIF 动画 要使用 Hotshot 生成 GIF 动画,您需要首先…...

吃鸡高手必备!这些技巧帮你提高战斗力!
大家好!作为一名吃鸡玩家,我们都想提高自己的战斗力,享受顶级游戏作战干货,装备皮肤库存展示和查询,并避免被骗游戏账号。在这里,我将为大家介绍一些实用的技巧和工具,让你成为吃鸡高手…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...