<script src="js/react.development.js">script>
<script src="js/react-dom.development.js">script>
<script src="js/babel.min.js">script>
编写hello world程序
下面编写的,不是真正的JavaScript代码,因为上面是JavaScript代码和html的混合,所以它的类型需要写成“text/babel”,最终通过编译器编译成浏览器可以执行的js
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>Documenttitle>
<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">
ReactDOM.render(
<h1>hello world!</h1>,
document.getElementById('root')
)
script>
body>
html>
二、JSX语法
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的结构还可以写得更复杂,可以是嵌套结构,如果是嵌套结构,需要有唯一的一个外层标签。标签中如果是单个的标签,在结尾要加“/”,在jsx中可以通过“{}”插入变量,表达式或者函数调用
<script type="text/babel">
let iNum01 = 10;
let sTr = 'abc123456';
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>
jsx标签属性值:jsx中指定标签的属性值建议用双引号,不能不用引号,属性名建议用驼峰式,其中class属性需要写成className,属性值如果是可变的,也可以写成“{}”的形式,里面可以和上面写法一样。 标签如果是单个的,在结尾一定要加“/”
{/* 定义class */}
<p className="sty01">使用样式p>
{/* 单个标签,结尾要加“/” */}
<img src={user.avatarUrl} />
示例:jsx语法
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>Documenttitle>
<style>
.sty01 {
font-size: 30px;
color: red;
}
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">
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>
{/* jsx里面的注释 */}
<p>{iNum01 + 5}</p>
<p>{sTr}</p>
<p>{sTr.split('').reverse().join('')}</p>
<p>{fnRev(sTr)}</p>
<p>{ok ? 'YES' : 'NO'}</p>
<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">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
<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 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>
);
}
}
// 渲染小的组件
//ReactDOM.render( , document.getElementById('root'))
// 渲染大的组件
ReactDOM.render(<WelcomeAll />, document.getElementById('root'))
script>
body>
html>
四、绑定事件
react绑定事件:React绑定事件和JavaScript中的行间事件类似,事件绑定是写在标签中的,但是,React事件是在原生事件的基础上做了封装,它的事件使用驼峰命名,而不是全部小写。事件需要传递一个函数作为事件处理程序,这个函数在哪里定义呢?我们可以通过类定义组件,将这个函数作为一个方法定义在组件中定义一个点击能d出名称的组件
class Helloname extends React.Component {
fnHello(){
alert('Hello,Tom');
}
render(){
return (
<input type="button" value="打招呼" onClick={this.fnHello} />
)
}
}
ReactDOM.render(<Helloname />, document.getElementById('root'));
组件定义成可以传递名称参数
需要注意的是,按钮在调用方法时,此时的this默认会指向这个按钮,所以在绑定事件时,需要绑定this,将this指向当前对象
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'));
示例:react绑定事件
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>Documenttitle>
<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 HelloTom extends React.Component {
//定义click事件的处理方法
fnHello() {
alert('Hello,Tom!');
}
render() {
return (
<input type="button" value="打招呼" onClick={this.fnHello} />
)
}
}
class HelloName extends React.Component {
//定义click事件的处理方法
fnHello() {
alert('Hello,' + this.props.name);
}
render() {
return (
// 在事件调用方法时,如果方法里面使用了this,在方法中需要绑定this
<input type="button" value="打招呼" onClick={this.fnHello.bind(this)} />
)
}
}
ReactDOM.render(<HelloName name="Jack" />, document.getElementById('root'));
script>
body>
html>
五、状态
组件的状态属性:组件如果需要定义默认属性呢?而且这个默认属性还是可变的呢?这个就是组件的状态属性了,状态属性默认名称是state,这个属性需要在组件定义时初始化,所以我们需要使用类的构造函数来对这个属性进行初始化定义一个点击按钮数字递增的
<!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>
<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 Increase extends React.Component {
constructor(props) {
super(props);
this.state = { iNum: 10 }
}
// 要通过setState方法来改变state里面的值
// setState里面可以传一个对象,也可以传一个函数,函数需要返回一个对象
fnAdd() {
/*
this.setState({
iNum:11
})
*/
// prevState 指的是state最新的值
/*
this.setState(function(prevState){
return { iNum:prevState.iNum+1}
})
*/
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>
state注意点1:不能直接修改state的值,应该用setState代替
// 下面写法是不会更新组件,是错误的
this.state.iNum = 11;
// 应该写成setState的形式
this.setState({iNum: 11});
state注意点2:state的值可能是异步的,如果需要在state的值的基础上修改得到新的值,可以使用函数的形式,函数的参数中传递的第一个参数是state上一个状态的值,我们可以在这个值基础上修改,下面的prevState代表state上一个状态的值
this.setState(prevState=>({
iNum:prevState.iNum+1
}));
案例:state实现选项卡
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>Documenttitle>
<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>
<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">
<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渲染这个对象就可以了通过map方法遍历数组中的成员,map方法的第二个参数是数组中的索引值,在循环生成li结构时,需要给每个li加上一个key,这个key的值可以用数组中的成员索引值
let aList = ['红海','复联3','碟中谍6','熊出没'];
let el = aList.map((item,i)=>
<li key={i}>{ item }</li>
);
ReactDOM.render(
<ul>{el}</ul>,
document.getElementById('root')
);
示例:列表渲染
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>Documenttitle>
<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">
let aList = ['红海', '复联3', '碟中谍6', '熊出没'];
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中的属性值
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>Documenttitle>
<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 }
}
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>todolisttitle>
<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: ''
}
}
fnChange(ev) {
this.setState({
sTodo: ev.target.value
})
}
fnAdd() {
this.setState(function (prevState) {
// 判断是否为空
if (prevState.sTodo == '') {
alert('请输入内容!')
return;
}
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.splice(i - 1, 0, nowItem);
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.splice(i + 1, 0, nowItem);
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
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>Documenttitle>
<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的数据交互:React没有集成ajax功能,要使用ajax功能,可以使用官方推荐的axios.js库来做ajax的交互。 axios库的下载地址 —— https://github.com/axios/axios/releasesaxios使用方法
url 请求地址method 请求方式,默认是’GET’,常用的还有’POST’responsetype 设置返回的数据格式,常用的是’json’格式,也可以设置为’text’或者’html’params 设置发送给服务器的数据then 设置请求成功后的回调函数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);
});
执行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);
});
案例:实现向服务器请求数据再渲染到组件上的todolist
除了数据请求部分使用componentDidMount实现,其他与之前的代码一直
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolisttitle>
<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>
<script src="js/axios.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: [],
sTodo: ''
}
}
componentDidMount() {
axios({
url: 'js/data.json',
method: 'get',
responsetype: 'json'
}).then(dat => {
console.log(dat.data);
let list = dat.data;
this.setState({
aList: list
})
}).catch(function () {
// alert('服务器超时!')
})
}
// 省略。。。与之前的代码一致
script>
body>
html>
十、脚手架开发
脚手架开发:脚手架开发指的是react提供了完整的自动化开发工具及规划好了开发一个应用的项目目录,这些工具是通过nodejs开发的,我们可以通过npm(nodejs包管理命令)来安装这些工具,同时可以通过这个工具生成一个应用的项目目录安装脚手架工具:脚手架工具是nodejs的一个包,安装这个工具之前需要先安装nodejs,然后在终端执行以下命令
1)设置npm淘宝镜像:npm config set registry https://registry.npm.taobao.org
2)安装:npm install -g create-react-app
生成应用项目目录:
生成app:create-react-app my-app
启动
cd my-app
npm start
生成上线文件:npm run build
项目目录说明
目录一:src目录,主开发目录,里面包含所有项目的组件,开发组件都是基于此目录目录二:public目录,项目入口文件目录,目录中的文件不用动目录三:项目开发依赖包文件目录,项目安装的包都会自动安装在这个文件夹中项目四:build目录,项目上线时,执行npm run build生成的目录,这里面是自动化工具生成的上线文件安装axios模块 1)在终端的项目目录,执行如下命令:
npm install axios
2)在模块文件中引入:import axios from 'axios';
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)