rem
em :段落,text-indent:2em 1个em == 1个字体的大小
(rem是移动端设计中的常用单位)
rem : 长度单位(描述字体大小,也可以描述宽高) ,1个rem == html中的fontSize大小
浏览器中默认的字体大小:16px 12px(最小)
(1rem = 16px )
sass的使用方法
变量
格式: $变量名称: 变量值
$color:#f00;
.content{
color: $color;
}
Nesting 内嵌
标记样式中继续定义子标记的样式
.a{
list-style: none;
border: 1px solid black;
li{
color: red;
}
}
.b{
font-size: 20px;
li{
font-weight: bold;
}
}
extend 继承
//定义父级
%parent {
font-size: 20px;
color: cornflowerblue;
font-family:'黑体';
}
//继承父级样式.child{ @extend %parent; font-weight: 300;}
## use 引入其他的sass样式
@use 会将所有的样式引入
```css
@use 'a4';
.exmaple{
color:a4.$color;
}
mixin 定义样式的函数
@mixin fn($primary-color:blue,$secondary-color:gray){
background-color: $primary-color;
color: $secondary-color;
font-size: 30px;
}
// 直接使用mixin函数
.a{
@include fn
}
// 对mixin函数的形参赋值
.b{
@include fn($primary-color:red,$secondary-color:black)
}
// 赋值的另一种形式
.c{
@include fn(red,black)
}
react
react是什么
React是一个用于构建用户界面的JavaScript库。用户界面: HTML页面(前端)React主要用来写HTML页面,或构建Web应用 如果从MVC的角度来看, React仅仅是视图层(V ) , 也就是只负责视图的渲染,而并非提供了完整的M和C的功能。
react的特点
声明式
基于组件
学习一次,随处使用
声明式
只需要描述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的基本使用
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,渲染的挂载位置
【案例:实现多个元素嵌套显示】
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)
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的思想
组件通讯介绍
组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据。在组件化过程中,我们将个完整的功能拆分成多个组件,以更好的完成整个应用的功能。而在这个过程中,多个组件之间不可避免的要共享某些数据。为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通。这个过程就是组件通讯。
组件的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接收状态或操作状态的方法
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组件 :用来消费数据
props深入(4props的默认值)
场景:分页组件 -> 每页显示条数
作用:给props设置默认值,在未传入props时生效
App.defaultProps = {
pageSize : 10
}
组件的生命周期
组件的生命周期(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 | 组件卸载(从页面中消失) | 执行清理工作(比如:清理定时器等) |