1. react的三大特点
-
声明式编程
- 声明式编程是目前整个大前端开发的模式:Vue、React、Flutter、SwiftUI
- 它允许我们只需要维护自己的状态,当状态改变时,React可以根据最新的状态去渲染我们的UI界面
-
组件化开发
- 组件化开发页面目前前端的流行趋势,我们会讲复杂的界面拆分成一个个小的组件
- 多平台的适配
2. JSX
- 【JSX】可以被看做是【JS】的扩展语法,它既不是【字符串,也不是一个html】,他包含一个JS的所有功能,当浏览器进行解析的时候,遇到【<>】,会当作html代码进行编译,在【JSX】创建DOM的时候,必须有根元素进行包裹
function App() {
return (
<div>
我是内容
</div>
)
}
export default App
2.1 JSX中书写JavaSscipt代码
- 通过在【JSX】语法的内部通过【{ }】的方式,对JavaScript代码进行包裹,浏览器遇到【{}】,就会当作JavaScript代码,进行编译
【 1. 动态显示数据与注释的添加 】
function App() {
const name = 'JSX语法'
return (
<div>
{ name }
{ /* 注释内容 */ }
</div>
)
}
export default App
【 2. JSX里可以的使用模板字符串 】
const name = '模板字符串'
function App() {
return (
<div> {`${name}`} </div>
)
}
export default App
【 3. 可以调用函数方法,也可以调用内置方法 】
const hello = () => {
console.log('你好 ')
}
function App() {
return (
<div>
{ hello() } // 调用方法
{ Math.random() } // 调用系统方法
{ console.log('JSX') }
</div>
)
}
export default App
【 PS: 在调用方法的时候,不仅仅可以调用自定义的方法,也可以调用系统内置的方法,进行使用 】
【 4. JSX中逻辑判断,只能够使用三元表达式,不支持if语句 】
const isShow = true
function App() {
return (
<div>{ isShow ? 'JSX' : 'react' }</div>
)
}
export default App
【 5. JSX语法本身就是语句,可以赋值给变量,可以当作函数的参数等 】
const dvs = <p>可以赋值给变量</p>
function App() {
return (
<div>
{ dvs }
</div>
)
}
【 6. 给元素添加属性 】
function App() {
return (
<div class={ age }></div>
)
}
export default App
【 PS:在给元素添加属性的时候,一般会存在两种情况,一种是普通的类名添加,另一种是通过给属性赋值【{变量}】 】
2.2 JSX事件
- 事件绑定
【 1. 事件绑定,事件驼峰命名法={ 事件处理名称 } 】
const handle =()=> {
console.log('JSX中的事件')
}
function App() {
return (
<div>
<button onClick={handle}>普通事件绑定</button> // 普通书写是不需要添加【(),如果加上括号就立即执行了】
<button onClick={() => {handle()}}>箭头函数绑定</button> // 通过箭头函数的方式绑定事件
</div>
)
}
export default App
【 2. bind绑定事件,类组件常用,它可以改变事件的this的指向 】
import React,{Component} from 'react'
class Heaber extends Component{
constructor () {
super();
this.state = { // 初始化状态
const: 0
}
this.handoler = this.handoler.bind(this) // 更改this操作(方式一)
}
render() {
return (
<div>
<button onClick={this.innerText.bind(this)}>bind</button>
</div>
)
}
innerText () {
this.setState({
const++
})
}
}
- 事件传参
【 1. 箭头函数的方式参数传递 】
const handle =(a,b) => {
console.log(a,b)
}
function App() {
return (
<div>
<button onClick={() => {handle(1,2)}} >箭头函数传参</button>
</div>
)
}
export default App
【 2. bind的方式进行参数传递 】
const handole = (a,b) => {
console.log(a,b)
}
function App() {
return (
<div>
<button onClick={handole.bind(null,1,2)}>bind传惨</button> // 参数传递从第二个参数开始
</div>
)
}
- 事件对象【如何获取事件对象】
【 1. 普通事件调用怎样拿到事件对象 】
const handole =(ev) => { 【普通函数,在事件绑定的时候是不需要传递的,默认接收一个事件对象】
console.log(ev)
}
function App() {
return (
<div>
<button onClick={handole}>普通事件</button>
</div>
)
}
【 2. 箭头函数方式传递事件对象 】
const handole =(ev) => { 【情况一】
console.log(ev)
}
const handole =(a,b,ev) => { 【情况二:如果在参数传递的时候,不仅仅传递了事件对象,还有其他参数,默认事件对象是最后被接收的】
console.log(a,b,ev)
}
function App () {
return (
<div>
<button onClock={(ev) =>{handole(ev)}}>箭头函数</button>
</div>
)
}
【 3. bind的方式是如何传递的 】
const handole = (a,b,ev) =>{ 【如果bind在传递参数时,没有传递事件对象,默认接收一个事件对象,是在其他参数之后接收的】
console.log(a,b,ev)
}
function App() {
return (
<button onClock={handole.bind(null,100,200)}>bind</button>
)
}
2.3 类组件中方法的this问题
【 例子: 】
import React,{Component} from 'react'
class App extends Component{
constructor () {
super();
this.state = { // 初始化状态
content: 0
}
}
render() {
return (
<div>
<button onClick={this.innerText}>bind</button>
</div>
)
}
innerText () {
console.log(this.state.content) // undefined state,
}
}
【 问题 】
* 在事件触发的时候,方法被调用,但是打印的是undefined state ,意思是undefined下面没有state属性,
问题就出在,绑定事件上【 回看 】
【 1. 解决方式一:在元素绑定事件的时候,通过bind将this改变 】
render() {
return (
<div>
<button onClick={this.innerText.bind(this)}>bind</button>
</div>
)
}
【 2. 解决方式二:在类组件的构造器中对this的绑定进行更改 】
constructor () {
super();
this.state = { // 初始化状态
content: 0
}
this.handoler = this.handoler.bind(this) // 对事件的this指向进行更改
}
【 3. 解决方式三:在书写事件程序的时候使用箭头函数的方式,由于箭头函数是没有this的,默认会向外面查找this 】
innerText = () => {
console.log(this.state.content)
}
【 4. 解决方式四:绑定时使用箭头函数 】
render() {
return (
<div>
<button onClick={() => {this.innerText()}}>bind</button>
</div>
)
}
3. 遍历数据
- 在react中,对数据的循环遍历,通过使用【高级方法map】对数据进行循环遍历,在对数据循环遍历的时,要给遍历的每一项加上一个【key】值,提高渲染的性能
const arr = [
{
id: 1,
name: 'jsx'
},
{
id: 2,
name: 'map'
}
]
function App() {
return (
<div>
<ul>
{
arr.map(item => {
return (
<li key={item.id}>{item.name}</li>
)
})
}
</ul>
</div>
)
}
export default App
3.1 后端返回数据,前端对数据进行截取
- 在有些开发的时候,前端向后端发送请求,请求数据,后端返回数据较多,但是,前端页面需求只需要很少的几条,这时,我们要对后端返回的数据进行截取操作,只截取需要的条数从前到后进行截取
【 调用数组的方法slice 】
【 循环数据并进行数据筛选 】
arr.slice(0,9).map(item => { // 在循环数组之前,对数据进行截取,然后返回新的数组,在进行遍历
return (
<li key={item.id}>{item.name}</li>
)
})
3.2 对数据进行过滤
【 循环数据并进行数据筛选 】
arr.filter(item => {
return 代码块
}).map(item => { // 在循环数组之前,对数据进行筛选,然后返回新的数组,在进行遍历
return (
<li key={item.id}>{item.name}</li>
)
})
4. 对样式的处理
- 在react中,动态绑定类名的话,是不能使用class,而是使用【className】
4.1 行内样式
【 1. 行内样式 】
const style = { // 方式二,注意是逗号隔开
width: 100,
height: 100
}
function App () {
return (
<div>
<button style={{ width:'100px' }}>方式一</button>【例如background-color == 必须使用驼峰方式】
<button style={ style }>方式二</button>
<button style={[ style,style ]}>方式三</button> 【 多个样式的写法】
【 可以使用三元表达式,决定哪一个类生效 】
</div>
)
}
【 2. 使用伪类 】
* 下载包,由于react中,不可以处理伪类,所以需要使用包,来处理伪类【npm install --save-dev radium】
import Radium from 'rudium'
const styles = {
backgroundColor: 'green',
":hover": {
backgroundColor: `rgb(0,0,1)`
}
}
function App() {
return () {
<button style={ styles } ></button>
}
}
export default Radium(App)
【 3. 媒体查询 index.js 入口文件】
import { StyleRoot } from 'radium'
ReactDOM.render(
<React.StrictMode>
// 需要使用改标签对组件进行包裹使用,这样设置的媒体查询可以进行使用
<StyleRoot> <App /></StyleRoot>
</React.StrictMode>,
document.getElementById('root')
);
4.2 外联样式
* 全局外联样式
【 引入,入口文件,app.js 】
import './app.css'
【 组件内部使用 】
function App() {
return (
<div className={ 'box' }></div>
)
}
export default App
* 单个组件外部样式
【 引入 】
* 在使用单个组件外联样式的时候,再给样式表命名的时候,一般采用两种形式,
第一种就是与组件名称相同,`某一个组件.module.css`
import style from '样式路径'
function App() {
return (
<div className={ style.某一个类名 } ></div>
)
}
export default App
5. 对于元素的属性的操作
【 1. img > src属性 】
* 有些时候,前端向后端请求数据,请求一些图片的数据,在这个时候,后端给前端返回一张非常大的图片
前端要根据页面,区调整图片的大小,这样调整,性能不是很好,当浏览器加载的时候,加载的是一个很大的
图,所以在后端返回图片的时候,需要对图片进行一些出处理,并不是通过css对图片进行设置
* 创建一个方法,用于处理图片的大小,一般在开发的时候,常见专门的处理图片的文件
function getImgUrl( imgUrl,size ) {
return imgUrl + `?param=${size} + ${size}` // 对大图进行处理
}
function App() {
return (
<div>
<img src={getImgUrl(图片地址,要设置的图片大小)}/>
</div>
)
}
【 2. 元素 > class属性 】
【 3. a > href属性 】
【 4. 元素 > style属性 】
【 5. label > for属性 】
6. JSX的本质(需要补充源码)
- 【JSX】的本质仅仅只是【React.createElement(component,props,...children)】的语法糖写法
- 所有的【JSX】最终都会通过【babel】进行转换,转换成【React.createElement】的函数调用
7. 初识虚拟DOM的创建过程(需要补充源码)
-
【JSX】转换成【React.createElement()】函数,在通过这个函数创建一个【ReactElement】对象
-
react通过【ReactElement】对象,去组成【JavaScript的对象树】
-
被组成出来的【JavaScript的树】就是【虚拟DOM】
-
【ReactElement】的结构
- 在react中是如何将【虚拟DOM】转换成真实的DOM,在react中通过【ReactDOM.render()】将【虚拟DOM】与【真实的DOM】【映射在一起(同步一起)】