高级特效开发笔记
rem
1、基于rem单位的屏幕等比例缩放
什么是rem
rem是浏览器描述长度的单位,含义为:相对于 html 的字体大小的单位。1rem = html 根节点上1个字符的宽度
rem的作用
使用 rem 单位设置的元素尺寸,会在不同的设备屏幕宽度下(例如:手机屏幕和平板屏幕)等比例缩放
应用场景
当页面元素需要在不同屏幕宽度下保证元素的比例大小不变时,则可以使用 rem
使用方法
请参考《自适应屏幕分辨率demo.html》
总结:
确立参考系,定义标准设备的屏幕宽度和字体大小
比例公式(等式左右两边比例尺相同,从而达到等比例缩放的目的):标准屏幕宽度 / 标准字体大小 = 新的屏幕宽度 / 新的屏幕字体大小
将页面样式中的 px 单位换算并替换为 rem,方法是 ?rem = 元素的尺寸 / 标准字体大小
绑定窗口的 resize 和 load 事件,触发事件时计算出新的屏幕宽度时的字体大小,设置 html 的字体大小
等比例缩放
2、元素的固定高度比例缩放
如何按比例设置元素的宽高
原理是:
一个父元素中的第一个子元素,其padding-top的百分比大小是参考的父元素的宽度
例如: padding-top: 25%,则子元素上侧内边距就是父元素宽度的25%
如此以来只要不设置父元素高度,则父元素的高度就是第一个子元素的高度,
从而让父元素宽高成比例
css预编译工具
什么是预编译?
编译?
将写好的代码文件进行编码和翻译
预编译?
预编译就是在编译环节发生之前,提前进行一次编译。其目的通常是将一个浏览器无法识别的语法提前编译成浏览器能够识别的语法。例如: css预编译 将 sass 转换为 css,js预编译 将 ts 转换成 js 等
那么,什么是css的预编译?
在浏览器运行脚本文件之前,进行一次编译并编译成可执行的css脚本
应用场景
项目足够大,样式足够复杂的时候可以使用预编译工具
项目中需要复用样式,且需要定义主题,复杂的计算等功能时,可以使用预编译工具
预编译工具sass
什么是sass
sass 工具用于对 css 进行预编译,预编译的css内容,是一个 sass/scss 文件,文件中的语法,大部分和 css 相同,有一部分是预编译的语法。
作用?
在 css 的基础上扩展一些实用的功能。
市面上流行的css预编译工具
Sass 官网:Sass: Sass Basics
Less 官网:http://lesscss.org/
Stylus 官网:https://stylus-lang.com/
安装
需要先安装node.js
npm install -g sass
命令行使用方法
# 语法 sass <inputPath> <outputPath>
# <inputPath> 要编译的 scss 或 sass 文件路径
# <outputPath> 编译完的 css 文件的输出路径
sass main.scss ./css/main.css
# 监视文件变化
# 添加 --watch 标识 可以让sass自动监视文件变化 然后自动输出到指定文件
sass --watch main.scss ./css/main.css
# 监视目录变化
# 路径参数变成 <inputDir>:<outputDir> 这样就可以监视文件夹中任一文件的变化并输出到对应文件夹
sass --watch ./sass:./css
bootstrap
1、bootstrap 介绍
中文临时网站:Get started with Bootstrap · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
bootstrap 的 github 地址:GitHub - twbs/bootstrap: The most popular HTML, CSS, and JavaScript framework for developing responsive, mobile first projects on the web.
bootstrap 是一个用于制作页面界面的框架
框架: 提供一个标准和规范,再由开发人员自行填充内容
(注意:目前最新版本为5.2, 实际开发效果最好以最新版为主,避免渲染错误)
2、下载安装
下载的文件说明:
下载 Bootstrap · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
下载dist文件
或者在 github 中下载 bootstrap 源代码,源代码中的 dist 文件夹就是我们要用的文件
npm 安装
npm i bootstrap
使用bootstrap
<!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>
<link rel="stylesheet" href="./css/bootstrap.min.css" />
</head>
<body>
<button type="button" class="btn btn-primary">Primary</button>
</body>
</html>
3、自定义主题
步骤如下:
下载 bootstrap 源代码
- 创建一个文件夹用于存放 bootstrap 源代码(建议使用英文文件夹)
- 在文件夹中打开 cmd
- 运行 npm init -y
- 运行 npm install bootstrap
根据需要修改 node_modules/bootstrap/scss 目录下的代码
运行 sass 进行编译,重新编译 bootstrap.scss 文件
输出 bootstrap.css 文件
总结sass内容
4、布局
响应式布局
响应式布局就是根据屏幕宽度,切换不同页面布局的一种布局方式,这里可以查看 bootstrap 官网在不同屏幕宽度下的表现
bootstrap 是使用断点来完成响应式布局的
断点
断点 · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
断点是 bootstrap 面向不同屏幕宽度,预制好的媒体查询
通常的将,断点,代表的就是不同的屏幕宽度
bootstrap中如何体现断点,在class中,添加不同断点的名称,可以采用不同断点的样式
布局容器
Containers · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
通常是页面的根节点,使用 class="container" 来设置布局容器
布局容器受断点影响,可以设置不同断点上的容器,具体可查表:
网格布局
Grid system · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
Columns · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
将内容进行行列分布的布局方式就叫网格布局
bootstrap中网格布局的灵魂样式就是 行:row,列:col
5、公共特征
display
参考:display 属性 · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
d-{value} for xs
d-{breakpoint}-{value} for sm, md, lg, xl, and xxl
/*value可以是以下值:*/
none
inline
inline-block
block
grid
table
table-cell
table-row
flex
inline-flex
![](file://C:\Users\archerswet\Desktop\高级特效开发\md-img\4-5-1.jpg?msec=1672969831024)
【案例】
根据4中的作业,利用d-修改网格布局结构
float
参考Float · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
float-{value}
float-{breakpointer}-{value}
/*value可以是以下值:*/
start
end
none
postiion
参考:Position · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
positon属性在bootstrap中的设置
<div class="position-static">...</div>
<div class="position-relative">...</div>
<div class="position-absolute">...</div>
<div class="position-fixed">...</div>
<div class="position-sticky">...</div>
位置属性:
top
start (替代left)
bottom
end (替代right)
属性值:
0 (百分之0,意思是首位)
50 (百分之50,意思是中部位置)
100 (百分之100,意思是尾部位置)
平移属性:
translate-middle (xy平移 -50%宽高)
translate-middle-x (x平移 -50%宽)
translate-middle-y (y平移 -50%高)
【案例】
![](file://C:\Users\archerswet\Desktop\高级特效开发\md-img\4-5-3.jpg?msec=1672969830968)
在按钮中添加消息提示
flex
参考:Flex · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
d-{breakpointer}-{inline}-flex
flex-{breakpointer}-{row|column}-{reverse}
justify-content-{breakpointer}
-{start|end|center|between|around|evenly}
align-items-{breakpointer}
-{start|end|center|baseline|stretch}
align-self-{breakpointer}
-{start|end|center|baseline|stretch}
color
参考:Colors · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
text-{color}
bg-{color}
btn-{color}
link-{color}
color的值为:
primary
secondary
success
danger
warning
info
light
dark
body
muted
white
black-50
white-50
sizing
参考:尺寸(Sizing) · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
百分比宽高:
w-25
w-50
w-75
w-100
w-auto
h-25
h-50
h-75
h-100
h-auto
视口(viewport)百分比宽高:
min-vw-100
min-vh-100
vw-100
vh-100
spacing
参考:Spacing · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
m margin
p padding
___
t top
b bottom
s start
e end
x left & right
y bottom & top
___
0
1
2
3
4
5
auto
stacks
参考:Stacks · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
vstack gap-{number}
hstack gap-{number}
--number--
0
1
2
3
4
5
text
参考:Text · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
text-{breakpointer}-{start|center|end}
text-{wrap|nowrap}
text-break
text-{lowercase|uppercase|capitalize}
---
fs-{number}
fw-{bold|bolder|semibold|normal|light|lighter}
fst
lh-{number|sm|base|lg}
---
text-decoration
6、表单(Form)
参考:Form controls · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
from-control
<input class="form-control" />
<input class="form-control from-lg|sm" />
<input class="form-control" disabled/>
<input class="form-control" disabled readonly/>
select
参考:Select · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
<select class="form-select" aria-label="Default select example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
checks & radios
参考:Checks and radios · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
<div class="from-check">
<input class="form-check-input" type="checkbox" value="" id="formCheck" />
<label class="form-check-label" for="formCheck">default check</label>
</div>
<div class="from-check">
<input class="form-check-input" type="checkbox" value="" id="formCheck2" />
<label class="form-check-label" for="formCheck2">item check</label>
</div>
<div class="from-check">
<input class="form-check-input" type="radio" name="sex" id="formSexMale" />
<label class="from-check-label" for="formSexMale" checked>Boy</label>
</div>
<div class="from-check">
<input class="form-check-input" type="radio" name="sex" id="formSexFeMale" />
<label class="from-check-label" for="formSexFeMale">Girl</label>
</div>
7、组件 (Component)
button
参考:Buttons · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-secondary">Secondary</button>
<button type="button" class="btn btn-success">Success</button>
<button type="button" class="btn btn-danger">Danger</button>
<button type="button" class="btn btn-warning">Warning</button>
<button type="button" class="btn btn-info">Info</button>
<button type="button" class="btn btn-light">Light</button>
<button type="button" class="btn btn-dark">Dark</button>
<button type="button" class="btn btn-link">Link</button>
button group
参考:Button group · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn btn-primary">Left</button>
<button type="button" class="btn btn-primary">Middle</button>
<button type="button" class="btn btn-primary">Right</button>
</div>
Card
参考:卡片(Cards) · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
<div class="card" style="width: 18rem;">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
dropdowns
参考:Dropdowns · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown button
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
modal
参考:Modal · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
navbar
参考:[Navbar · Bootstrap v5 中文文档 v5.2 | Bootstrap 中文网 (bootcss.com)
React
01-react概述
React是一个用于构建用户界面的JavaScript库。
用户界面: HTML页面(前端)
React主要用来写HTML页面,或构建Web应用
如果从MVC的角度来看, React仅仅是视图层(V ) , 也就是只负责视图的渲染,而并非提供了
完整的M和C的功能。
声明式
基于组件
学习一次,随处使用
声明式
只需要描述UI(HTML)是什么样,React负责渲染UI,并在数据变化时更新UI
const jsx = <div className="app">
<h1>React动态变化:{count}</h1>
</div>
基于组件
组件时React最重要的内容
组件表示页面中的部分内容
组合、复用多个组件,可以实现完成的页面功能
学习一次,随处使用
使用React可以开发Web应用
使用React可以开发移动端原生应用( react-native )
使用React可以开发VR(虚拟现实)应用(react360)
React的安装
安装命令:npm i react react-dom
react 包是核心,提供创建元素、组件等功能
react-dom 包提供DOM相关功能等
React的使用
1、引入react和react-dom 两个js文件
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
2、创建React元素
<script>
const title = React.createElement('h1',null,'Hello React')
</script>
3、渲染React元素
ReactDOM.render(title,document.getElementById('root'))
方法说明:
React.createElement
参数1:元素名称
参数2:元素属性
参数3...:元素的子节点(文本、标记...)
ReactDOM.render
参数1:要渲染的React元素
参数2:DOM,渲染的挂载位置
【案例:实现多个元素嵌套显示】
02-react脚手架
React脚手架意义
脚手架是开发现代Web应用的必备。
充分利用Webpack、 Babel、 ESLint等I具辅助项目开发。
零配置,无需手动配置繁琐的工具即可使用。
关注业务,而不是工具配置。
使用React脚手架初始化项目
1、初始化项目,命令:npx create-react-app 项目名称( my-app)
2、启动项目,在项目根目录执行命令:npm start (yarn start)
npx命令介绍
npm v5.2.0 引入的一 条命令
目的:提升包内提供的命令行工具的使用体验
以前:先安装脚手架包,再使用这个包中提供的命令
现在:无需安装脚手架包,就可以直接使用这个包提供的命令
补充:
1.推荐使用: npx create-react-app my-app
2.npm init react-app my-app
3.yarn create react- app my-app
yarn 是Facebook发布的包管理器,可以看做是npm的替代品,功能与npm相同
yarn具有快速、可靠和安全的特点
初始化新项目: yarn init
安装包: yarn add包名称
安装项目依赖项: yarn
其他命令,请参考yarn文档
在脚手架中使用React
1.导入react和react-dom两个包。
import React from 'react'
import ReactDOM from 'react-dom'
2.调用React.createElement(方法创建react元素。
3.调用ReactDOM.render(方法渲染react元素到页面中。
react基础阶段总结
React是构建用户界面的JavaScript库
使用react时,推荐使用脚手架方式。
初始化项目命令: npx create-react-app my-app。
启动项目命令: yarn start (或npm start )。
【案例】(关于模块化知识的使用)外部组件的定义
03-JSX的基本使用
createElement的问题:
1.繁琐不简洁。
2.不直观,无法一眼看出所描述的结构。
3.不优雅,用户体验不爽。
JSX简介
JSX是JavaScript XML的简写,表示在JavaScript代码中写XML ( HTML )格式的代码。
优势:声明式语法更加直观、与HTML 结构相同,降低了学习成本、提升开发效率
JSX使用步骤
1、使用JSX语法创建react元素
const title = <h1>Hello JSX</h1>
2、使用ReactDOM.render() 方法渲染react元素到页面
ReactDOM.render(title,root)
为什么脚手架中可以使用JSX语法
JSX不是标准的ECMAScript语法,它是ECMAScript的语法扩展。
需要使用babel编译处理后,才能在浏览器环境中使用。
create-react-app脚手架中已经默认有该配置,无需手动配置。
编译JSX语法的包为: @babel/preset-react。
JSX的注意点
React元素的属性名使用驼峰命名法
特殊属性名: class -> className、for -> htmlFor、tabindex -> tabIndex
没有子节点的React元素可以用 /> 结束
推荐:使用小括号包裹JSX,从而避免JS中的自动插入分号陷阱
在JSX中使用JavaScript表达式
数据储存在JS中
语法:{JavaScript表达式}
JSX的条件渲染
场景:loading效果
条件渲染:根据条件渲染特定的JSX结构
可以使用if/else或三元运算符或逻辑与运算符来实现
JSX的列表渲染
如果要渲染一组数据,应该使用数组的map()方法
注意:渲染列表时应该添加key属性,key属性的值要保证唯一
原则: map()遍历谁,就给谁添加key属性
注意:尽量避免使用索引号作为key
const students = [
{id:1,name:'张三'},
{id:2,name:'李四'},
{id:3,name:'王五'},
]
const list = {
<ul>
{students.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
}
JSX的样式处理
1、行内样式-style
<h1 style={{color:'red',backgroundColor:'blue'}}> JSX行内样式 </h1>
2、类名-className(推荐)
需要引入css
import './css/index/css'
【案例:将指定json数据渲染至网页中】
fetch(url)
.then(response => { response.json(()=>{}).then(...).then(...) })
JSX阶段总结
JSX React的核心内容。
JSX 示在JS代码中写HTML结构,是React声明式的体现。
使用JSX配合嵌入的JS表达式、条件渲染、列表渲染,可以描述任意UI结构。
推荐使用className的方式给JSX添加样式。
React 完全利用JS语言自身的能力来编写UI ,而不是造轮子增强HTML功能。
04-React组件介绍
组件是React的一等公民,使用React就是在用组件
组件表示React实现的部分功能
组合多个组件实现完整的页面功能
特点:可复用、独立、可组合
组件的两种创建方式(1函数组件)
函数组件:使用JS的函数(或箭头函数)创建的组件
注意:函数名称必须以大写字母开头
注意: 函数组件必须有返回值,表示该组件的结构
注意:返回值为null,就不显示任何内容
function Hello(){
return (
<div>函数组件</div>
)
}
渲染函数组件:用函数名作为组件标签名
组件标签可以是单标签,也可以是双标签
ReactDOM.render(<Hello />,root)
组件的两种创建方式(2类组件)
类组件:使用ES6的class创建的组件
注意:类名称必须以大写字母开头
注意:类组件应该继承React.Component 父类,从而可以使用父类中提供的方法或者属性
注意:类组件必须提供render()方法
注意:render() 方法必须用return返回值,表示该组件的结构
class Hello extends React.Component{
render(){
return <div>Hello Class Component!</div>
}
}
ReactDOM.render(<Hello />,root)
组件的两种创建方式(3抽离为独立js文件)
1、创建Hello.js
2、在Hello.js中导入React
3、创建组件(函数 或 类)
4、在Hello.js 中导出该组件
5、在index.js 中导入Hello 组件
6、渲染组件
import React from 'react'
class Hello extends React.Component{
render(){
return <div>Hello Class Component!</div>
}
}
export default Hello
React事件处理(1事件绑定)
React事件绑定语法与DOM事件语法很相似
语法: on+事件名称 = {事件处理程序},比如:onClick = {()=>{}}
注意:React事件采用驼峰法命名, 比如:onMouseEnter,onFocus
如果在函数组件中绑定事件,则调用事件函数不加this
class App extends React.Component {
handleClick(){
console.log('被点击了')
}
render(){
return (
<button onClick={this.handleClick()}></button>
)
}
}
React事件处理(2事件对象)
可以通过事件处理程序参数获取到事件对象
React中的事件对象叫做:合成事件(对象)
合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题
function handleClick(e){
e.preventDefault()
console.log('事件对象',e)
}
<a onClick={handleClick}>点击跳转</a>
有状态组件和无状态组件
函数组件又叫做无状态组件,类组件又叫做有状态组件
状态(state)即数据
函数组件没有自己的状态,只负责数据展示(静态)
类组件有自己的状态,负责更新UI(动态)
state的基本使用
状态(state)即数据,是组件内部的私有数据,只能在组件内部使用
state的值是对象,表示一个组件中可以有多个数据
通过this.state 来获取状态
class Hello extends React.Component {
constructor(){
super()
this.state = {
count:0
}
}
render(){
return (
<div>有状态组件</div>
)
}
}
ES6简化语法
class Hello extends React.Component {
state = {
count:0
}
render(){
return (
<div>有状态组件</div>
)
}
}
【案例】有状态组件中的state可以定义哪些数据,如何调用
组件中的state和setState()(1setState()修改状态)
状态时可变的
语法:this.setState({要修改的数据})
注意:不能直接修改state中的值
setState()作用:1、修改state 2、更新UI
数据驱动视图
class Hello extends React.Component {
state = {
count:0
}
render(){
return (
<div>计数器:{this.state.count}</div>
<button onClick={()={
this.setState({
count:this.state.count + 1
})
}}>+1</button>
)
}
}
组件中的state和setState()(2从JSX中抽离事件处理程序)
JSX中有太多的JS逻辑代码,会使程序混乱
推荐:将逻辑抽离到单独的方法中,保证JSX结构清晰
class Hello extends React.Component {
state = {
count:0
}
onIncrement(){
this.setState({
count:this.state.count + 1
})
}
render(){
return (
<div>计数器:{this.state.count}</div>
<button onClick={this.onIncrement()}>+1</button>
)
}
}
尝试将事件函数剥离JSX,我们会有:
TypeError:Cannot read property 'setState' of undefined
原因:事件处理程序中this的值为undefined
希望:this指向组件实例(render方法中的this即为组件实例)
无状态组件的state
const [count,setCount] = React.useState(0)
const [number,setNumber] = React.useState(1)
事件绑定this指向(1箭头函数)
利用箭头函数自身不绑定this的特点
class Hello extends React.Component {
state = {
count:0
}
onIncrement(){
this.setState({
count:this.state.count + 1
})
}
render(){
return (
<div>计数器:{this.state.count}</div>
<button onClick={()=>this.onIncrement()}>+1</button>
)
}
}
事件绑定this指向(2bind)
利用ES5中的bind() 方法,将事件处理程序中的this与组件实例绑定到一起
class Hello extends React.Component {
state = {
count:0
}
constructor(){
super()
this.onIncrement = this.onIncrement.bind(this)
}
onIncrement(){
this.setState({
count:this.state.count + 1
})
}
render(){
return (
<div>计数器:{this.state.count}</div>
<button onClick={()=this.onIncrement()>+1</button>
)
}
}
事件绑定this指向(3class的实例方法)
利用箭头函数形式的class实例方法
注意:改语法是实验性的,但babel可以转化该语法
class Hello extends React.Component {
state = {
count:0
}
onIncrement = ()=>{
this.setState({
count:this.state.count + 1
})
}
render(){
return (
<div>计数器:{this.state.count}</div>
<button onClick={this.onIncrement}>+1</button>
)
}
}
事件绑定this指向-总结
1、推荐:使用class的实例方法
2、箭头函数
3、bind
表单处理(1受控组件概念)
HTML中的表单元素是可输入的,也就是有自己的可变状态
而React中可变状态通常保存在state中,并且只能通过setState() 方法来修改
React将state与表单元素值value绑定到一起,由state的值来控制表单元素的值
受控组件:其值受到React控制的表单元素
表单处理(2受控组件使用步骤)
受控组件设置步骤:
1、在state中添加一个状态,作为表单元素的value值(控制表单元素值的来源)
2、给表单元素绑定change事件,将表单元素的值,设置为state的值(受控表单元素值的变化)
state = {txt:''}
<input type="text" value={this.state.txt} onchange={e =>
this.setState({txt : e.target.value})} />
表单处理(3受控组件的示例)
富文本框textarea
state = {content:''}
handleContent = e=>{
this.setState({
content:e.target.value
})
}
<textarea value={this.state.content} onChange={this.handleCOntent}>
</textarea>
下拉框select
state = {city:'bj'}
handleCity = e=>{
this.setState({
city:e.target.value
})
}
<select value={this.state.city} onChange={this.handleCity}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="gz">广州</option>
</select>
复选框
state = {
isChecked:false
}
handleCheck = e => {
this.setState({
isChecked:e.target.value
})
}
<input type="checkbox" checked={this.state.isChecked}
onChange={this.handleCheck}/>
表单处理(4多表单元素优化)
每个表单元素都有一个单独的事件处理程序处理太繁琐
使用一个事件处理程序同时处理多个表单元素
多表单元素优化步骤
1、给表单元素添加name属性,名称与state相同
<input type="text" \
name="txt"
value={this.state.txt}
onChange={this.handleForm}/>
2、根据表单元素类型获取对应值
const value = target.type === 'checkbox' ? target.checked : target.value
this.setState({
[name]:value
})
表单处理(5非受控组件)
1、调用React.createRef() 方法创建一个ref对象
constructor(){
super()
this.txtRef = React.createRef()
}
2、将创建好的ref对象添加到文本框中
<input type="text" ref={this.txtRef} />
3、通过ref对象获取到文本框的值
console.log(this.txtRef.current.value)
【案例:取消购物车选中】
【作业:多表单控制】
React组件基础总结
1、组件的两种创建方式:函数组件和类组件
2、无状态(函数)组件,负责静态结构展示
3、有状态 (类) 组件,负责更新UI,让页面动起来
4、绑定事件注意this指向问题
5、推荐使用受控组件来处理表单
6、完全利用JS语言的能力创建组件,这是React的思想
05-React组件基础综合案例(1案例需求分析)
【案例】评论列表
1)渲染评论列表(列表渲染)
2)没有评论数据时渲染:暂无评论(条件渲染)
3)获取评论信息,包括评论人和评论内容(受控组件)
4)发表评论,更新评论列表(setState() )
【作业】表格控制(要求使用bootstrap 控制表单样式)
React组件进阶学习目标
06-组件通讯介绍
组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据。在组件化过程中,我们将个完整的功能拆分成多个组件,以更好的完成整个应用的功能。而在这个过程中,多个组件之间不可避免的要共享某些数据。为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通。这个过程就是组件通讯。
组件的props(1基本使用)
组件是封闭的,要接收外部数据应该通过props来实现
props的作用:接收传递给组件的数据
传递数据:给组件标签添加属性
接收数据:函数组件通过参数props接收数据,类组件通过this.props接收数据
<Hello name="jack" age={19} />
function Hello(props){
console.log(props)
return (
<div>接收到数据:{props.name}</div>
)
}
class Hello extends React.Component{
render(){
return (
<div>接收到的数据:{this.props.name}</div>
)
}
}
组件的props(2特点)
1、可以给组件传递任意类型的数据 (除了常见的数值、字符串、数组之外,还可以传递函数和标记等等)
2、props是只读的对象,只能读取属性的值,无法修改对象
(注意:使用类组件时,如果写了构造函数,应该将props传递给super(),否则,无法在构造函数中获取到props)
组件通讯的三种方式(1父组件传递数据给子组件)
1、父组件提供要传递的state数据
2、给子组件标签添加属性,值为state中的数据
3、子组件中通过props接收父组件中传递的数据
class Parent extends React.Component{
state = { name:'zhangsan' }
render(){
return (
<div>
传递给子组件:<Child name={this.state.name} />
</div>
)
}
}
function Child(props){
return <div>子组件接收到数据:{props.name}</div>
}
组件通讯的三种方式(2子组件传递数据给父组件)
1、附件提供一个回调函数(用于接收数据)
2、将该函数作为属性的值,传递给子组件
3、子组件通过props调用回调函数
class Parent extends React.Commponent{
getChildMsg = msg =>{
console.log('接收到子组件数据',msg)
}
render(){
return (
<div>
子组件:<Child getMsg={this.getChildMsg} />
</div>
)
}
}
class Child extends React.Component {
state = { childMsg: 'React'}
handleClick(){ this.props.getMsg(this.childMsg) }
return (<button onClick={this.handleClick}></button>)
}
组件通讯的三种方式(3兄弟组件通讯)
将共享状态提升到最近的公共组件中,由公共父组件管理这个状态
思想:状态提升
公共父组件职责:1、提供共享状态 2、提供操作共享状态的方法
要通讯的子组件只需要通过props接收状态或操作状态的方法
【作业:组件封装】
【作业:秒表】
07-Context的基本使用
问题:如果需要Parent层层将数据传递给子组件中的子组件,该如何处理
处理方式:使用props一层层往下传递(繁琐)
更好的方式:使用Context,实现跨组件传递数据(比如:主题、语言等)
使用步骤:
1、调用React.createContext() 创建Provider (提供数据)和Consumer(消费数据)两个组件。
const {Provider,Consumer} = React.createContext()
2、使用Provider组件作为父节点
<Provider>
<div className="App">
<Child1 />
</div>
</Provider>
3、 设置value属性,表示要传递的数据
<Provider value="blue">
4、调用Consumer 组件接收数据
<Consumer>
{data => <span>data参数表示接收到的数据 -- {data}</span>}
</Consumer>
总结:
如果两个组件是远方亲戚(比如,嵌套多层)
可以使用Context实现组件通讯
Context提供 了两个组件: Provider和ConsumerProvider组件 :用来提供数据
Consumer组件 :用来消费数据
08-props深入
props深入(1children属性)
children 属性:表示组件标签的子节点。当组件标签由子节点时,props就会有该属性
children属性与普通的props一样,值可以时任意值(文本、React元素、组件、甚至是函数)
function Hello(props){
return (
<div>
组件的子节点:{props.children}
</div>
)
}
<Hello>子节点</Hello>
props深入(2props校验)
对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据
如果传入的数据格式不对,可能会导致组件内部报错
关键问题:组件的使用者不知道明确的错误原因
function App(props){
const arr = props.colors
const lis = arr.map((item,index) => <li key={index}>{item.name}</li>)
return (
<ul>{lis}</ul>
)
}
<App colors={19}/>
props校验:允许在创建组件的时候,就指定props的类型、格式等
作用:捕获使用组件时因为props导致的错误,给出明确的错误提示,添加组件的健壮性。
App.propTypes = {
colors:PropTypes.array
}
使用步骤:
1、安装包prop-types (yarn add prop-types / npm i prop-types)
2、导入prop-types包
3、使用组件名.propTyps = {}给组件的props添加校验规则
4、校验规则通过PropTypes 对象来指定
import PropTypes from 'prop-types'
function App(props){
return (
<h1>Hi,{props.colors}</h1>
)
}
App.propTypes = {
colors:PropTypes.array
}
props深入(3props校验-约束规则)
约束规则
1、常见类型:array、bool、func、number、object、string
2、React元素类型:element
3、必填项:isRequired
4、特定结构的对象: shape({ })
//常见类型
optionalFunc: PropTypes.func,
// 必选
requiredFunc: PropTypes.func.isRequired,
//特定结构的对象
optionalObjectwithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
})
使用 PropTypes 进行类型检查 – React (reactjs.org)
练习:
添加props校验
属性a的类型:数值(number)
属性fn的类型:函数(func)并且为必填项
属性tag的类型:React元素(element )
属性filter的类型:对象({area:'上海',price: 1999})
App.propTypes = {
a: PropTypes.number,
fn: PropTypes.func.isRequired ,
tag: PropTypes.element ,
filter: PropTypes.shape({
area: PropTypes.string,
price: PropTypes.number
})
props深入(4props的默认值)
场景:分页组件 -> 每页显示条数
作用:给props设置默认值,在未传入props时生效
App.defaultProps = {
pageSize : 10
}
09-组件的生命周期
组件的生命周期(1概述)
意义:组件的生命周期有助于理解组件的运行方式、完成更复杂的组件功能,分析组件错误原因等
组件的生命周期:组件从被创建到挂载到页面中运行,再到组件不用时卸载的过程
生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的钩子函数。
钩子函数的作用:为开发人员在不同阶段操作组件提供了时机。
只有类组件才有生命周期
组件的生命周期三个阶段(1创建时)
执行时刻:组件创建时(页面加载时)
执行顺序:constructor -> render -> componentDidMouunt
| 钩子函数 | 触发时机 | 作用 |
| ----------------- | ------------- | -------------------------- |
| constructor | 创建组件时,最先执行 | 1、初始化state 2、为事件处理程序绑定this |
| render | 每次组件渲染都会触发 | 渲染UI(注意:不能调用setState()) |
| componentDidMount | 组件挂载(完成DOM渲染) | 1、发送网络请求 2、DOM操作 |
组件的生命周期三个阶段(2更新时-1触发时机)
1、有新的props传入
2、setState方法被调用
3、forceUpdate执行
组件的生命周期三个阶段(2更新时-2钩子函数说明)
更新时的执行顺序:render -> componentDidUpdate
| 钩子函数 | 触发时机 | 作用 |
| ------------------ | ------------- | -------------------------------------------------- |
| render | 每次组件渲染都会触发 | 渲染UI(注意:不能调用setState()) |
| componentDidUpdate | 组件更新(完成DOM渲染) | 1、发送网络请求 2、DOM操作 (setState必须放置在if条件中,默认参数preProps) |
组件的生命周期三个阶段(3卸载时)
执行时刻:组件从页面中消失
| 钩子函数 | 触发时机 | 作用 |
| -------------------- | ------------ | ----------------- |
| componentWillUnmount | 组件卸载(从页面中消失) | 执行清理工作(比如:清理定时器等) |
组件的生命周期三个阶段(4不常用钩子函数介绍)
1、shouldComponentUpdate(组件性能优化)
2、getSnapshotBeforeUpdate
生命周期图示:
时间轴:
10-错误边界
部分 UI 的 JavaScript 错误不应该导致整个应用崩溃,为了解决这个问题,React 16 引入了一个新的概念 —— 错误边界。
错误边界是一种 React 组件,这种组件可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI,而并不会渲染那些发生崩溃的子组件树。错误边界可以捕获发生在整个子组件树的渲染期间、生命周期方法以及构造函数中的错误。
其中重要方法是
componentDidCatch(error, errorInfo) {
// 你同样可以将错误日志上报给服务器
logErrorToMyService(error, errorInfo);
}
11-Fragments
React 中的一个常见模式是一个组件返回多个元素。Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。
(主要解决子组件包裹元素的问题)
方式一:
class Columns extends React.Component {
render() {
return (
<React.Fragment>
<td>Hello</td>
<td>World</td>
</React.Fragment>
);
}
}
方式二:
class Columns extends React.Component {
render() {
return (
<>
<td>Hello</td>
<td>World</td>
</>
);
}
}
12-Portals
Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。
ReactDOM.createPortal(child, container)
第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或 fragment。(第一个参数一般情况下是 this.props.children)
第二个参数(container)是一个 DOM 元素。
Protals的特征实际应用在 弹窗、确认框、警告等窗口设计中
13-Profiler
Profiler 测量一个 React 应用多久渲染一次以及渲染一次的“代价”。
Profiler 能添加在 React 树中的任何地方来测量树中这部分渲染所带来的开销。 它需要两个 prop :一个是 id(string),一个是当组件树中的组件“提交”更新的时候被React调用的回调函数 onRender(function)。
分析Navigation组件和它的子代们:
render(
<App>
<Profiler id="Navigation" onRender={callback}>
<Navigation {...props} />
</Profiler>
<Main {...props} />
</App>
);
多个Profiler组件能测量应用中的不同部分
render(
<App>
<Profiler id="Navigation" onRender={callback}>
<Navigation {...props} />
</Profiler>
<Profiler id="Main" onRender={callback}>
<Main {...props} />
</Profiler>
</App>
);
嵌套使用Profiler组件来测量相同一个子树下的不同组件:
render(
<App>
<Profiler id="Panel" onRender={callback}>
<Panel {...props}>
<Profiler id="Content" onRender={callback}>
<Content {...props} />
</Profiler>
<Profiler id="PreviewPane" onRender={callback}>
<PreviewPane {...props} />
</Profiler>
</Panel>
</Profiler>
</App>
);
onRender 回调
function onRenderCallback(
id, // 发生提交的 Profiler 树的 “id”
phase, // "mount" (如果组件树刚加载) 或者 "update" (如果它重渲染了)之一
actualDuration, // 本次更新 committed 花费的渲染时间
baseDuration, // 估计不使用 memoization 的情况下渲染整棵子树需要的时间
startTime, // 本次更新中 React 开始渲染的时间
commitTime, // 本次更新中 React committed 的时间
interactions // 属于本次更新的 interactions 的集合
) {
// 合计或记录渲染时间。。。
}
14-构建 React.js 的UI框架
Material-UI 一套实现 Google Material Design 的 React 组件
地址:Overview - Material UI (mui.com)
React Desktop MacOS Sierra 和 Windows 10 的 React UI 组件。
Semantic-UI Semantic-UI 的官方 React 组件
Ant-design一套企业级的前端设计语言和基于 React 的前端框架实现。
Blueprint 针对构建复杂、数据密集的 Web 界面的桌面应用进行了最优化。如果你重度依赖移动互动,并且正在寻找 mobile-first 的 UI 工具包,它可能不适合你。
React-BootstrapReact-Bootstrap 是一个可重复使用的前端组件库。你可以通过 Facebook 的 React.js 框架获得 Twitter Bootstrap 的体验,而且有更为清晰的代码
React-Toolbox 一组使用 CSS 模块实现 Google Material Design 的 React 组件。
Grommet 用于企业应用最先进的 UX 框架。
Fabric 用于构建与 Office 和 Office 365 界面相类似的 Web 应用的 React 组件。
React-md 一个实现 Material Design 的库。React-md 可以轻松地根据自己的需要进行定制,拥有良好的文档和快速上手的“入门”指南,以及许多常见的 Material 组件。
Material-UI(MUI)使用
安装MUI
npm install @mui/material @emotion/react @emotion/styled
快速使用
import * as React from 'react';
import Button from '@mui/material/Button';
export default function MyApp() {
return (
<div>
<Button variant="contained">Hello World</Button>
</div>
);
}
React-Bootstrap
React进阶
render props和高阶组件概述(1)
render props模式(1思路分析)
render props模式(2使用步骤)
render props模式(3演示Mouse组件的复用)
render props模式(4children代替render属性)
render props模式(5代码优化)
高阶组件(1介绍)
高阶组件(2使用步骤)
高阶组件(3设置displayName)
高阶组件(4传递props)
React组件进阶总结
React原理揭秘学习目标
setState()方法的说明(1更新数据)
setState()方法的说明(2推荐语法)
setState()方法的说明(3第二个参数)
JSX语法的转化过程
组件更新机制
组件性能优化(1减轻state)
组件性能优化(2避免不必要的重新渲染1)
组件性能优化(2避免不必要的重新渲染-随机数案例)
组件性能优化(2避免不必要的重新渲染-随机数案例2)
组件性能优化(3纯组件-基本使用)
组件性能优化(3纯组件-shallow compare)
虚拟DOM和Diff算法
虚拟DOM和Diff算法(代码演示)
React原理揭秘总结
React路由基础学习目标
React路由介绍
路由的基本使用
路由的基本使用(常用组件说明)
路由的执行过程
编程式导航
默认路由
匹配模式(1模糊匹配模式)
匹配模式(2精确匹配)
React路由基础总结
JSX语法的转化过程
1、JSX是createElement()的简化语法
2、JSX语法被@babel/preset-react 插件编译为createElement()方法
3、React元素:是一个对象,其结构用来描述在页面中的内容
组件更新机制
setState的两个作用:1、修改state 2、更新组件(UI)
过程:父组件重新渲染时,也会重新渲染子组件。但只会渲染当前组件以及所有子节点
组件性能优化
减轻state
减轻state:只储存跟组件渲染相关的数据 (比如:count/列表数据/loading等)
不做渲染的数据不要放在state中,例如定时器的id
对于这种需要在多个方法中用到的数据,应该放在this中
避免不必要的重新渲染
组件更新机制:父组件更新会引起子组件也被更新
问题关键:子组件没有任何变化时也会重新渲染
避免不必要重新渲染的解决方式 shouldComponentUpdate(nextProps,nextState)
作用:通过返回值决定该组件是否重新渲染,返回true表示重新渲染,false表示不重新渲染。
触发时机:更新阶段的钩子函数,组件重新渲染前执行(shouldComponentUpdate -> render)
案例:随机数(父组件->子组件)
React-props和高阶组件
如果两个组件有部分功能相似或相同,则我们复用其state 和操作state的方法
有两种方式:1、render props模式 2、高阶组件(HOC)
引用类型中的比较
const obj = {number:0}
const newobj = obj
newobj.number = 2
console.log(newobj === obj)
引发的错误问题,以下是错误做法:
state = {obj:{number:0}}
state.obj.number = 2
setState({obj:state.obj})
//因为最新的state.obj === 上一次的state.obj //true 不重新渲染
正确的方式:
const newobj = {...this.state.obj,number:'新的值'}
setState({obj:newobj})
例子:数组的更新方式
虚拟DOM 和 Diff算法
如果整个组件只有一个DOM元素需要更新,不会把整个组件内容渲染到页面中
虚拟DOM:本质上就是一个JS对象,用来描述显示的UI内容
虚拟DOM
const element = {
type:'div',
props:{
className:'box',
children:'Hello World'
}
}
HTML 结构
<h1 class="box">
Hello World
</h1>
执行过程
1、初次渲染,react根据state,创建一个虚拟DOM对象(树)
2、根据虚拟DOM生成真正的DOM,渲染到页面中。
3、当数据变化后(setState()),重新根据新的数据,创建新的虚拟DOM对象(树)
4、与上一次得到的虚拟DOM对象,使用Diff算法对比(找不同),得到需要更新的内容。
5、最后,将变化内容patch(更新)到DOM中,重新渲染到页面.
React路由基础(Router-Route)
现代前端应用大多都是SPA(单页应用程序),也就是只有一个HTML页面的应用程序。
用户体验更好,对服务器的压力小
前端路由的根本作用,就是页面相互跳转
React前端路由是URL路径与组件的对应关系(配置路径和组件)
使用步骤:
1、安装 npm add react-router-dom
2、导入路由的三个核心组件:Router / Route / Link
import {BrowserRouter as Router,Route,Link} from 'react-router-dom'
3、使用Router组件包裹整个应用
<Router>
<div className="App">
...
</div>
</Router>
4、使用Link组件作为导航菜单(路由入口)
<Link to="/first">页面一</Link>
5、使用Router组件配置路由规则和要展示的组件(路由出口)
const First = ()=> <p>页面一的页面内容</p>
<Router>
<div className="App">
<Link to="/first">页面一</Link>
<Route path="/first" component={First}></Route>
</div>
</Router>
常用组件说明
Router组件:包裹真个应用,一个React应用只需要用一次
Link组件,用于指定导航链接a标记 to就是location.pathname
Route组件,指定路由展示组件的内容
编程式导航
通过JS代码来实现页面跳转
history 是React路由提供的,用于获取浏览器历史记录的相关信息
push(path) 跳转到某个页面,参数path表示要跳转的路径
go(n) 前进或后退到某个页面。参数n表示前进或后退页面数量(-1,上一页)
this.props.history,push('/home')
默认路由
<Route path="/" component={Home}></Route>
精确匹配模式
了解模糊匹配模式
<Route exact path="/" component={Home}></Route>