react框架是当前较为流行的一种框架,它主要用于较为大型的项目。react框架与vue框架类似。以下主要学习了以下vue的指令在react中如何实现。
1.react的下载:
在命令窗口,下载react脚手架包:
yarn global add create-react-app
2.创建项目:
在命令窗口,输入以下内容创建react项目:
create-react-app 项目名
3.了解项目:
使用webStorm,VS Code或者HBulider 打开你的项目。可以看到一些文件,其中
package.json里面是项目一些基本的配置,如如何开始、打包项目,项目的依赖包等。
src文件夹是我们主要的写代码的地方。在src中,index.js文件是根实例,将根组件App渲染到public文件夹中index.html中的挂载点上。其内容比较固定。
// 使用jsx对象(例如:<App />)时,必须引入react
import React from 'react';
import ReactDOM from 'react-dom';
// 导入根组件
import App from './App.jsx';
// 第一个参数;要渲染什么。第二个参数:要渲染到哪里
ReactDOM.render( <App />, document.getElementById('root'));
src文件夹中的App.jsx是根组件。定义根组件有两种方法:类组件,函数组件。
什么是jsx对象?相对于vue中的template。
react组件必须要指定一个render函数,该函数必须要返回一个jsx对象或null。
以下使用的是类组件。
// react组件的自定义就是要继承自React.Component的类
import React, { Component } from 'react';
class App extends Component {
constructor() {
super(); // 可以使用父组件中的构造函数
this.state = { // 放需要渲染的数据
}
}
render() { // return中写html代码,返回jsx对象
return {( // 写html代码时,可以用()包裹
<div><div> // 只有一个根节点
)};
}
}
src文件夹中的App.css是修饰根组件的样式,不过若多个css文件夹中有相同的class值,会造成渲染混乱。所以我们一般使用App.module.css,准确找到需要的样式。
import style from './App.module.css'; // 导入样式文件
render() {
return {
<div className={style["container"]></div>
};
}
4.基础功能实现:
在以下功能中,使用的数据都来自constructor中的this.state中。函数来自与constructor,render同级的自定义函数。
1.类似vue中的v-text指令:
<span>{this.state.name}</span>
2.类似vue中的v-if指令:
<div>
{this.state.isShow && ( // this.state.isShow为真时,显示后面的内容
<div>显示内容</div>
)}
</div>
3.类似vue中的v-if + v-else指令:
<div>
{this.state.isShow ? (
<div>为真显示的内容</div>
) : (
<div>为假显示的内容</div>
)}
</div>
4.类似vue中的v-if + v-else-if + v-else指令:
可以通过函数间接实现该指令,不过函数要返回一个jsx对象。
// render()函数周围
judge() { return jsx对象 }
// render()函数returnjsx对象中
<div>
{this.judge}
</div>
5.类似vue中的v-for指令:
<ul>
{this.state.data.map((item,i) => ( // 简单类型的数组
<li key={i}>{item}</li>
))}
</ul>
6.类似vue中的v-show指令:
无法直接实现,动态改变class值来实现。在CSS中设置一个class值show:display block;另一个class值hidden: display: none;来回切换class实现v-show指令。
<span className={this.state.isShow ? style["show"] : style["hidden"]}>显示</span>
7.类似vue中的v-bind指令:
可以实现动态和静态class值同时存在。
// 共有两种方式实现:
<span className={["aaa", this.state.isShow ? style["show"] : ""].join(" ")}>显示</span>
<span className={`aaa ${ this.state.isShow ? style["show"] : "" }`>显示</span>
8.类似vue中的v-on指令:
给标签绑定事件。使用on+事件名,例如点击事件onClick。
事件绑定不传参(默认传事件对象e):
<button onClick={this.clickHandler}>点我</button>
事件绑定传参(写成箭头函数):
<button onClick={() => this.clickHandler2(100)}>点我</button>
使用事件绑定时还需要注意函数中this指针的指向问题。若想让react事件绑定函数中的this指针指向当前的组件本身,有三个方法:
1.在当前组件的构造函数中进行bind调用,绑死this。
优点:当该函数为父组件传给子组件的函数时,父组件中函数的刷新不会导致子组件中函数无意义的刷新。
缺点:需要再constructor中书写额外的代码
constructor() {
super();
this.state = {};
this.clickHandler = this.clickHandler.bind(this)
}
clickHandler() {}
<button onClick={this.clickHandler}></button>
2.在绑定函数时,直接用bind绑定this指针。
优点:不需要在constructor中写额外的代码。
缺点:当该函数为父组件传给子组件的函数时,父组件中函数的刷新,都会执行bind表达式产生一个新的与上一个相同的函数,但子组件会认为这是一个不同的函数,导致子组件无意义的刷新。
clickHandler() {}
<button onClick={this.clickHandler.bind(this)}></button>
3.利用ES6类定义高级特性,在类定义函数时,使用箭头函数,让this绑死当前组件。
clickHandler = () => {};
<button onClick={this.clickHandler}></button>
9.修改state中的数据:
必须使用this.setState()来修改state中的数据。
constructor() {
super();
this.state = {
name: '张三',
arr: [{id: 1, name: '张三'}, {id: 2, name: '李四'}],
obj: { id: 3, name: '王五' }
};
}
// 简单修改数据
this.setState({ name: '李四' }); // 运行后state中的name数据会发生改变'李四'
// 运行后state中obj中的值会变成'李四'
this.setState({ obj: Object.assign({}, this.state.obj, { name: '李四' }) })
// 操作arr
let arr = this.state.arr;
arr[0].name = "李四";
this.setState({ arr });
// 运行后,state中的arr的第一个对象中的name值为李四
this.setState()中可以是对象,也可以是函数。其区别在于:
如果是对象(this.setState({}))的话,在同一段同步代码中不论迭代多少次,它只执行最后一次的操作。
如果是对象(this.setState(state => {}))的话,在同一段同步代码中后面setState中的数据要用到前面setState中的结果。
this.state = {
a: 0,
b: 0
}
for(let i = 0; i < 100; i++) {
this.setState({ a: this.state.a + 1 });
this.setState(state => { a: state.a + 1 });
}
// 操作执行结束后,a: 1, b: 100
以上是今天学习react框架的成果。