第一章、react项目搭建
- 安装
npm i create-react-app -g
- 创建项目
create-react-app 项目名称
- 函数式组件
// 导入组件的样式
import './Two.css'
// 函数式组件,就是一个普普通通的js函数,导出
export default function Two() {
// 定义的数据
let name = 'Two'
let age = 20
let sex = '男'
let list = [
{ id: 1, name: '周杰伦', age: 20, sex: '男' },
{ id: 2, name: '薛之谦', age: 22, sex: '男' },
{ id: 3, name: '林俊杰', age: 24, sex: '男' },
]
let ageStyle = { fontSize: '20px', color: 'red' }
// 父元素点击事件
let clickParent = () => {
alert('你好我是parent')
}
// 子元素的点击事件
let clickChild = (e) => {
console.log(e);
// 阻止事件冒泡
e.stopPropagation();
alert('你好我是child')
}
let clickA = (e) => {
// 阻止事件默认行为
e.preventDefault()
alert('点击了百度')
}
// 函数中的返回的内容,就是组件中的内容
// jsx语法:就是在{}里面写js表达式
return <div className='two'>
{/* 绑定行内样式 */}
<p style={{ fontSize: '20px', color: 'lightblue' }}>姓名:{name}</p>
<p style={ageStyle}>年龄:{age}</p>
{/* 指定一个类选择器 */}
<p className='sex'>性别:{sex}</p>
<ul>
{/* 列表渲染的语法 */}
{list.map((r, i) => {
return <p key={i}>{r.id + ' ' + r.name + ' ' + r.age + ' ' + r.sex}</p>
})}
</ul>
<div className='parent' onClick={clickParent}>
<div className='child' onClick={clickChild}></div>
</div>
<a href="https://baidu.com" onClick={clickA}>百度</a>
</div>
}
- 类组件
import { Component } from "react";
// 导入组件的样式
import './One.css'
// 类组件必须继承Component基类
export default class One extends Component {
// 在state中定义状态数据
state = {
display: 'block',
// 数据
list: [
{ title: '南京', content: '南京的盐水鸭真不错!!' },
{ title: '苏州', content: '苏州没有机场!!!' },
{ title: '杭州', content: '杭州西湖风景很美丽' },
{ title: '合肥', content: '合肥有什么!!!' },
],
// 高亮索引
activeIndex: 0
}
// 注意:这里的方法必须采用箭头函数,这样方法中的this才能指向组件
changeDisplay = () => {
let { display } = this.state
if (display === 'block') {
display = "none"
} else {
display = "block"
}
// 更新状态,需要调用setState方法
this.setState({
display
})
}
changeActive = (e) => {
this.setState({
activeIndex: e
})
}
// 通过render 方法,返回组件内容
render() {
let name = 'One'
let age = 25
let sex = '女'
let { display, list, activeIndex } = this.state
return <div className='one'>
<p>姓名:{name}</p>
<p>年龄:{age}</p>
<p>性别:{sex}</p>
{/* jsx里面是事件就是,网页原生的事件,只是要采用小驼峰命名 */}
<button onClick={this.changeDisplay}>显示/隐藏</button>
<div className="box" style={{ display }}>
<img src="https://img1.baidu.com/it/u=3184485295,1843016893&fm=253&fmt=auto&app=138&f=JPEG?w=501&h=500" alt="" />
</div>
<ul className='titles'>
{list.map((r, i) => {
return <li className={activeIndex === i ? 'active' : ''} onClick={() => this.changeActive(i)} key={i}>{r.title}</li>
})}
</ul>
<div>{list[activeIndex].content}</div>
</div >
}
}
第二章、react的增删改
import React, { Component } from 'react'
import './Four.css'
export default class Four extends Component {
state = {
list: [
{ no: '1001', name: '李飞', age: 22, sex: '男' },
{ no: '1002', name: '李华', age: 21, sex: '男' },
{ no: '1003', name: '李翔', age: 23, sex: '男' },
{ no: '1004', name: '李鹏', age: 24, sex: '男' },
],
stu: {
no: '',
name: '',
age: '',
sex: ''
},
// 是否时编辑状态
isEdit: false
}
// 更新学生数据
changeStu = (key, vlaue) => {
this.setState({
stu: {
...this.state.stu,
[key]: vlaue
}
})
}
// 添加
add = () => {
this.setState({
list: [...this.state.list, this.state.stu]
})
}
// 删除
del = (e) => {
// let { list } = this.state
// list.splice(e, 1)
// this.setState({
// list
// })
this.setState({
list: this.state.list.filter((r, index) => index !== e)
})
}
// 编辑
updateFn = (s) => {
this.setState({
stu: s,
isEdit: true
})
}
// 修改
updateStu = () => {
let index = this.state.list.findIndex(r => r.no === parseInt(this.state.stu.no))
this.state.list.splice(index, 1, this.state.stu)
this.setState({
list: this.state.list
})
}
render() {
let { list, stu, isEdit } = this.state
return (
<div className='four'>
<table>
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{list.map((r, i) => {
return (
<tr key={i}>
<td>{r.no}</td>
<td>{r.name}</td>
<td>{r.age}</td>
<td>{r.sex}</td>
<td>
<button onClick={() => this.updateFn(r)}>编辑</button>
<button onClick={() => this.del(i)}>删除</button>
</td>
</tr>
)
})}
</tbody>
</table>
<hr />
<table>
<tbody>
<tr>
<td>学号:</td>
<td>
<input disabled={isEdit} type="text" value={stu.no} onChange={(e) => { this.changeStu('no', e.target.value) }} />
</td>
</tr>
<tr>
<td>姓名:</td>
<td>
<input type="text" value={stu.name} onChange={(e) => { this.changeStu('name', e.target.value) }} />
</td>
</tr>
<tr>
<td>年龄:</td>
<td>
<input type="text" value={stu.age} onChange={(e) => { this.changeStu('age', e.target.value) }} />
</td>
</tr>
<tr>
<td>性别:</td>
<td>
<input type="text" value={stu.sex} onChange={(e) => { this.changeStu('sex', e.target.value) }} />
</td>
</tr>
<tr>
<td></td>
<td>
{/*isEdit是否为真为真的话显示修改按钮,否则显示添加按钮 */}
{isEdit ?
<button onClick={this.updateStu}>修改</button> :
<button onClick={this.add}>添加</button>
}
<button onClick={() => {
this.setState({
stu: {
no: '',
name: '',
age: '',
sex: ''
},
isEdit: false
})
}}>取消</button>
</td>
</tr>
</tbody>
</table>
</div>
)
}
}
第三章、组件之间的通信
- 父向子传递数据 props
// 父组件
export default class Five extends Component {
state = {
message: '欢迎光临!'
}
// 修改数据
setMessage = (i) => {
this.setState({
message: i
})
}
render() {
let { message, address, carNme, color } = this.state
return (
<div className='five'>
<h2>父组件</h2>
<p>消息:{message}</p>
<button onClick={() => { this.setMessage('谢谢惠顾') }}>修改消息</button>
</div>
)
}
}
// 定义子组件
class Child1 extends Component {
render() {
return <div style={{
border: '1px solid #ccc', padding: '5px'
}}>
<h3>Child1子组件</h3>
<p>消息:{this.props.message}</p>
//修改子组件里面的值需要在父组件里面定义方法通过this.props调用父组件里面的方法
<button onClick={() => { this.props.setmessage('哈哈') }}>子组件</button>
</div>
}
}
- 父组件向孙子组件传递数据
// 父组件
//导入组件的上下文容器 createContext
import React, { Component, createContext } from 'react'
export default class Five extends Component {
state = {
carNme: '奔驰GLC260',
color: '白色'
}
render() {
let { message, address, carNme, color } = this.state
return (
<div className='five'>
<h2>父组件</h2>
{/* 通过provider定义依赖数据 */}
<Context.Provider value={{ carNme, color }}>
<Child3 />
</Context.Provider>
</div >
)
}
}
// 在组件的内部使用这个容器
let content=createContext ()
//孙子组件
function Son3() {
return <div style={{
border: '1px solid #ccc', padding: '5px'
}}>
<h3>Son3孙组件</h3>
{/* 通过consumer注入父元素中设置的依赖数据 */}
<Context.Consumer>
{({ carNme, color }) => {
return <div>
<p>汽车名称:{carNme}</p>
<p>汽车颜色:{color}</p>
</div>
}}
</Context.Consumer>
</div>
}
第四章、props验证类组件
import React, { Component } from 'react'
import './Seven.css'
import PropTypes from "prop-types"
// 类子组件
class Child extends Component {
// 给props设置默认值
static defaultProps = {
num1: 1000,
num2: 2000
}
render() {
let { num1, num2, array, fun, one, obj, obj2 } = this.props
return <div style={{ border: '1px solid #ccc' }}>
<h3>Child</h3>
<p>{num1}+{num2}={num1 + num2}</p>
<ul>
{array.map((r, i) => {
return <li key={i}>{i + 1}.{r}</li>
})}
</ul>
<button onClick={fun}>点击</button>
{one}
<div>
{JSON.stringify(obj)}
</div>
<div>
{JSON.stringify(obj2)}
</div>
</div>
}
}
// 给Child组件的props设置类型
Child.propTypes = {
// 通过给指定的props设置类型
num1: PropTypes.number,
num2: PropTypes.number,
array: PropTypes.array,
// isRequired表示必须传递
func: PropTypes.func.isRequired,
one: PropTypes.element,
// 必须传递一个对象
obj: PropTypes.object,
// 验证对象的格式
obj2: PropTypes.shape({
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
sex: PropTypes.string.isRequired
})
}
// 函数式子组件的props默认值,直接给参数赋值
function Child2({ num1 = 1000, num2 = 2000 }) {
return <div style={{ border: '1px solid #ccc' }}>
<h3>Child</h3>
<p>{num1}+{num2}={num1 + num2}</p>
</div>
}
// 函数式组件的props类型约束,跟类组件是一样的
Child.propTypes = {
// 通过给指定的props设置类型
num1: PropTypes.number,
num2: PropTypes.number,
}
// 父组件
export default class Seven extends Component {
render() {
return (
<div className='seven'>
<h2>Seven</h2>
<Child
// num没有传递但是有默认值
num1={100} num2={200}
array={['西瓜', '苹果', '桃子']}
fun={() => { alert('我是一个函数') }}
one={<p>你好!!</p>}
obj={{ name: '李四', age: 22, sex: '男', height: 165 }}
obj2={{ name: '李四', age: 22, sex: '男', height: 165 }}
></Child>
<Child2 num1={2000} num2={3000}></Child2>
</div >
)
}
}
第五章、react的生命周期函数
// 生命周期
import React, { Component } from 'react'
// 类子组件,只有类组件才有生命周期函数,函数组件没有生命周期函数
class Child extends Component {
state = {
count: 5,
}
constructor(props) {
super(props);
console.log('1.构造函数:组件加载时最先执行.....');
}
render() {
console.log('2.render渲染函数:在组件开始挂载页面是执行,页面第一次挂载和状态更新后都会执行....');
return <div style={{ border: '1px solid #ccc' }}>
<h3>Child</h3>
<p>数量:{this.state.count}</p>
<button onClick={() => {
this.setState({ count: this.state.count + 1 })
}}>数量++</button>
</div>
}
componentDiMount() {
console.log('3.componentDiMount组件挂载完成....');
}
componentDidUpdate() {
console.log('4.componentDidUpdate组件状态更新后页面重新挂载完成....');
}
componentWillUnmount() {
console.log('5.componentWillUnmountz组件将要卸载....');
}
}
// 类父组件
export default class Eight extends Component {
state = {
show: true
}
render() {
let { show } = this.state
return (
<div className='eight'>
<h2>Eight</h2>
<button onClick={() => {
this.setState({
show: !show
})
}}>显示/隐藏</button>
{show && <Child></Child>}
</div>
)
}
}