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 动画,您需要首先…...
吃鸡高手必备!这些技巧帮你提高战斗力!
大家好!作为一名吃鸡玩家,我们都想提高自己的战斗力,享受顶级游戏作战干货,装备皮肤库存展示和查询,并避免被骗游戏账号。在这里,我将为大家介绍一些实用的技巧和工具,让你成为吃鸡高手…...
XV6 操作系统实验
环境搭建 ubuntu 新建一个文件setup.sh,内容如下 #获取工具链 git clone --recursive https://github.com/riscv/riscv-gnu-toolchain #安装必要依赖 sudo apt-get update sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev li…...
leetcode - 双周赛114
一,2869.收集元素的最小操作次数 // 解法:哈希表 从右往左遍历 class Solution {public int minOperations(List<Integer> nums, int k) {Set<Integer> set new HashSet<>();for(int i1; i<k; i){set.add(i);}for(int inums.size…...
【LeetCode刷题笔记】双指针
剑指 Offer 21.调整数组顺序使奇数位于偶数前面 解题思路: 对撞指针 , 从左边不停的找第一个偶数,从右边不停的找第一个奇数 ,找到后 交换 两者位置 本题与【905. 按奇偶排序数组】几乎雷同。 剑指 Offer 57.和为s的两个数字 本题…...
互联网Java工程师面试题·Memcached 篇·第二弹
目录 10、memcached 如何实现冗余机制? 11、memcached 如何处理容错的? 12、如何将 memcached 中 item 批量导入导出? 13、如果缓存数据在导出导入之间过期了,您又怎么处理这些数据呢? 14、memcached 是如何做身份…...
特斯拉被称为自动驾驶领域的苹果
特斯拉的自动驾驶技术无疑是居于世界上领先地位的,有人形容特斯拉是自动驾驶汽车领域的苹果。特斯拉发布的Tesla Vision系统只配备了摄像头,不依靠雷达。 这并不是特斯拉唯一和其它对手不同的地方,他们的整个战略都是基于车队和销售产品,而其大多数竞争对手则销售自…...
stm32之HAL库操作PAJ75620
一、模块简介 手势模块PAJ7620主要利用IIC或SPI协议来实现数据的传输,本实验用的模块是以IIC来进行信息传输。支持电压从2.8v到3.6v, 正常可以选择3.3v。检测的距离从5到15cm, 可以检测9种手势,包括 右:编码为 0x01左:编码为 0x0…...
医学影像归档与通讯系统(PACS)系统源码 PACS三维图像后处理技术
医学影像归档与通讯系统(PACS)系统源码 PACS三维图像处理 医学影像归档与通讯系统(PACS)系统,是一套适用于从单一影像设备到放射科室、到全院级别等各种应用规模的医学影像归档与通讯系统。PACS集患者登记、图像采集、…...
web漏洞-PHP反序列化
目录 PHP反序列化序列化反序列化原理涉及技术利用危害CTF靶场 PHP反序列化 序列化 将对象转换成字符串 反序列化 相反,将字符串转换成对象。 数据格式的转换对象的序列化有利于对象的保存和传输,也可以让多个文件共享对象。 原理 未对用户输入的序列化字…...
Redis-分布式锁
分布式锁相关内容 超卖问题切入可以使用互斥锁给先获取到锁的线程加锁吗?使用redis分布式锁解决超卖问题setnx命令实现分布式锁为什么需要设置过期时间?Redis实现分布式锁如何合理控制锁的有效时长 redisson实现分布式锁 超卖问题切入 我们先来看一个项目…...
什么时候使用继承,好莱坞原则(设计模式与开发实践 P11+)
文章目录 好莱坞原则真的需要继承吗? 好莱坞原则 如果你熟悉继承方法、乃至模板方法模式后,就可以了解一个设计原则 好莱坞原则 新人演员把简历发给好莱坞,许久之后没有回应不耐烦打电话给好莱坞,只收到回应:不要来找…...
网站的收费标准/大数据获客系统
1 什么是设计模式? 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。简单点说,设计模式就是对问题行之有效的解决方式,是一种思想。 2 什么是模板方法模式?…...
网站建设注意事项知乎/seo查询是什么意思
1.显示文件的所有行,但忽略以#开头的行;hello.txt文件第一行有一个#号执行程序:2. 逐页显示文本文件的程序,用户输入一个文件名,每次默认显示行数为10行,给用户一个选项,"是否继续?(Y|N)"方法1:方法2&#…...
wordpress文件夹分类/山东东营网络seo
plannar模式:三维分开存储 在AVFrame::data[]中存储如下: data[0]——-Y分量, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8…, Y16, … data[1]——-U分量, U1, U2, U3, U4…… data[2]——-V分量, V1, V2, V3, V4…… 其中"——-"代表 data[0]指向Y分量开…...
C 建设个人网站/网络公司seo教程
主要总结 JavaScript的六种数据类型:Boolean、Number、String、Null、Undefined、Object 布尔类型 布尔真假判定:短路原则 x && y 只有在x和y都为真的情况下为真。即真真为真,短路:因比较运算为左结合运算,若…...
上海全国网站建设/网络舆情的网站
Oracle OCP认证专家级人才培养方案说明会<?xml:namespace prefix st1 ns "urn:schemas-microsoft-com:office:smarttags" />9月11日在天津举办 改变你职业生涯的机会来了<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office&…...
sap.net怎么做网站/今天的热点新闻
夜光序言: 如果爱你可以让你幸福,那我就爱你;如果爱你不能让你幸福,那我就只喜欢你. 正文: 以道御术 / 以术识道 // pages/category/category.js //0 引入 用来发送请求的 方法 一定要把路径补全 import…...