华清远见重庆中心-高级特效开发阶段学习总环

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


sass

一、什么是CSS预处器

CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。通俗的说,CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,以供项目使用。CSS预处理器为CSS增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在CSS中使用变量、简单的逻辑程序、函数等等在编程语言中的一些基本特性,可以让你的CSS更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。

1.1 Sass背景介绍

Sass是对CSS(层叠样式表)的语法的一种扩充,诞生于2007年,最早也是最成熟的一款CSS预处理器语言,它可以使用变量、常量、嵌套、混入、函数等功能,可以更有效有弹性的写出CSS。Sass最后还是会编译出合法的CSS让浏览器使用,也就是说它本身的语法并不太容易让浏览器识别,因为它不是标准的CSS格式,在它的语法内部可以使用动态变量等,所以它更像一种极简单的动态语言。

其实现在的Sass已经有了两套语法规则:一个依旧是用缩进作为分隔符来区分代码块的;另一套规则和CSS一样采用了大括号({})作为分隔符。后一种语法规则又名SCSS,在Sass3之后的版本都支持这种语法规则。

注:Sass官网地址:http://sass-lang.com

二、把Sass编译成css

2.1 安装

安装推介B站良心up主:Sass windows安装教程

2.2 创建项目

  • 在你需要的地方创建项目,然后在编辑器中打开该目录

  • 这里我创建的项目是,ninghao-sass

  • 在ninghao-sass目录下创建一个文件夹sass,在该文件夹下新建文件style.scss 该目录用于存放项目所有的sass文件

  • 在ninghao-sass目录下创建一个文件夹css,在该文件夹下新建文件style.scss 该目录用于存储编译好的css文件
    在这里插入图片描述

  • 然后我们在style.scss中输入

body{
    font-size: 15px;
}

2.3 打开命令行工具,把这个sass文件编译成普通的css文件

首先要进入到项目 目录下 也就是ninghao-sass
输入命令: sass (要编译的文件):(要输出的css文件)
sass sass/style.scss:css/style.css

  • 完成以后,css文件夹下会出现编译好的css文件

2.4 自动编译

  • sass --watch (要监视的目录):(指定编译后的目录)
  • sass --watch sass:css
  • ctrl+c 可以取消自动编译

2.5 Sass编译方式

  • 更改Sass编译方式的方法 --style [compact,expanded,compressed]
  • 更改编译方式命令:sass --watch sass:css --style compact
2.5.1nested 嵌套 (默认)

在这里插入图片描述

2.5.2compact 紧凑

在这里插入图片描述

2.5.3expanded 扩展

在这里插入图片描述

2.5.4compressed 压缩

在这里插入图片描述

三、Sass 与 less的区别

  • 扩展名不一样
  • Sass 是 .sass
  • less 是 .scss (常用)

四、Scss的变量

  • 使用 $符号+名称 可以定义变量
  • 变量里可以使用另外一个变量
    在这里插入图片描述

4.1 嵌套写法

  • 效果和注释掉的一模一样
    在这里插入图片描述

  • 不过如果在写伪类的时候这样写的话会出现下面这种情况

  • 可以看到编译过后的css文件会多出一个空格
    在这里插入图片描述

  • 这个时候我们只需要在伪类标签前添加 & 符号即可
    在这里插入图片描述

4.2 引用父选择器

Scss

/* 嵌套时调用父类选择器*/
.nav{
    height: 100px;
    &  &-item{
        font-size: 10px;
    }
}

Css

.nav .nav-item{
  font-size: 10px;
}

五、嵌套属性

对于同一个选择器下,相同的属性名称,我们可以提取出来。例如:

.nav{
    border:1px solid #000;
    border-left: 0;
    border-right: 0;
} 

可以写成

.nav{
    border:1px solid #000{
        left:0;
        right: 0;
    }
}

在这里插入图片描述

可以发现,编译后的css文件四一模一样的。

六、mixin (类似JS函数)

可以把它想象成是,有名字的、定义好的样式
可以在任何地方,重复使用,可以把它当作是JS的函数

你可以使用使用@符号定义它,例如:

@mixin 名字(参数1,参数2){
	...
}

mixin 可以嵌套使用变量,子样式、或者其他mixin 例如:

@mixin alert {
    color: #8a8a8a;
    background-color: #fcf8e3;
    @include test;
    a{
        color: green($color: #000000);
        @include test;
    }
}
@mixin test {
    font-weight: 15px;
}

.alert-waring{
    @include alert;
}
  • 第一:我们首先定义了一个alert,然后在里边添加了一些样式,
  • 第二:我们引入了另外的一个mixin
  • 第三:我们在alert这个mixin下,又定义了一个a的样式。接下来我们看看会编译成什么样子
    在这里插入图片描述

可以看到,效果是非常不错的,不仅嵌套的test编译出来了,而且子级的a样式,也成功编译。

6.1 darken (加深指定的颜色)

darken(参数1,参数2)

  • 参数1:要加深的颜色
  • 参数2:百分比加深多少
    在这里插入图片描述

6.2 调用mixin

默认我们调用mixin的时候,参数需要对应。
但是当我们指定参数的时候,就可以不用对应。例如:
注意:指定参数的时候需要使用 : 号 来紧跟对应的值
在这里插入图片描述

七、@extend 继承或者扩展

在Sass中我们可以使用@extend来减少重复的动作
在这里插入图片描述

继承相当于把继承类的类名换成当前类的类名。并且样式是继承类的样式。
简单来说,就是我把你的变成我们共同的。
当我们使用@extend继承的时候,右边编译后的css文件会出现群组选择器。它们会同时拥有在群组选择器里边的样式。

八、 @import 与 Partials

Partials文件名要以 _ (下划线开头)

那么如何引入Partials文件呢?

在文章开头,我们使用 @import + “文件名;” 的方式即可,
不需要写下划线,也不需要写扩展名,在同级目录下不需要写路径
在这里插入图片描述

九、注释

9.1、多行注释

  • 会在编译输出的结果中保留 但在压缩方式的编译情况下会去掉
/*
这是多行注释
天王盖地虎
*/

9.2、单行注释

  • 不会出现在编译输出之后的文件里面。
//这是单行注释

9.3、强制注释

  • 这样注释的内容,会一直出现在css里边
/*!这是强制注释*/

在这里插入图片描述

十、Data Type

  • 在命令行中我们输入 sass -i

  • 这是sass提供的交互功能,在这之后你输入的内容回车之后会立刻看到结果。
    在这里插入图片描述

  • 判断数据的类型 可以使用 type-of()

  • 数据类型的数字还可以包含单位 例如:

当然还有很多其他用法 例如:
在这里插入图片描述

十一、number 运算

  • 在sass交互模式下,试一下数字的运算
    在这里插入图片描述

十二、数字函数

  • abs() 取绝对值
  • round() 四舍五入
  • ceil() 向上取整
  • floor() 向下取整
  • percentage() 取百分比
  • min(1,2,3) 取最小的
  • max(1,2,3) 取最大的
    在这里插入图片描述
    在这里插入图片描述

十三、String 字符串

带引号:可以包含空格,和一些其他特殊字符
不带引号:不能有空格

  • 号 - 号 / 号 都可以连接字符串
>> "ning" + hao
"ninghao"
>> ning + "hao"
"ninghao"

在这里插入图片描述

十四、字符串函数

在Sass中有一些函数可以处理字符串类型的数据。

14.1 to-upper-case() 全部转为大写

在这里我们先定义了一个变量 $greeting,然后把该变量作为to-upper-case()函数的参数,可以发现,该字符串的英文全部转化为大写了。

PS F:\Node.js\Node_project\ninghao-sass> sass -i
>> $greeting:"hello,world"
"hello,world"
>> $greeting
"hello,world"
>> to-upper-case($greeting)
"HELLO,WORLD"
>>

14.2 to-lower-case() 全部转为小写

用法同上。

PS F:\Node.js\Node_project\ninghao-sass> sass -i
>> $greeting:'Hello,World'
"Hello,World"
>> to-upper-case($greeting)
"HELLO,WORLD"
>> to-lower-case($greeting)
"hello,world"
>>

14.3 str-length() 返回字符串长度

用法同上。

>> str-length($greeting)
11
>>

14.4 str-index() 返回指定字符在字符串中首次出现的位置

注意:索引是从1开始的

>> $greeting:'Hello,World'
>
>> str-index($greeting,'world')
null
>> str-index($greeting,'World')
7
>>

14.5 str-insert() 插入字符串

语法: str-insert(要往那个字符串插入,插入的是什么,插入的位置)

>> str-insert($greeting,',Good morning',12)
"Hello,World,Good morning"

你也可以在str-insert函数中嵌套使用其他函数,比如:

>> str-insert($greeting,',Good morning',str-length($greeting)-5)
"Hello,Good morning,World"
>>

十五、颜色

在css里边表示颜色的方式有很多种,
例如:
#FF0000 16进制
rgb(255,0,0) RGB方式 红,绿,蓝
还有一些常用的字符类型的 比如 red black white blue

15.1 颜色函数 RGB与RGBA

rgb(红,绿,蓝)
rgba(红,绿,蓝,透明度(0-1));
a:完全透明-完全不透明

body{
    background-color: rgba(255, 255, 0,1);
}

15.2 颜色函数 hsl与hsla

hsl语法:色相,饱和度,明度
色相:0°-360°
饱和度:0-100%
明度:0-100%
hsla语法:基本同上,和rgba差不多

15.3颜色函数 adjust-hue

adjust-hue(),可以调整色相的值。
语法:adjust-hue(要调整的对象,参数)
在这里插入图片描述

15.4 颜色函数 lighten与darken

lighten与darken可以改变颜色的明度
lighten可以让颜色更白,越大越接近白色
darken可以让颜色更黑,越大越接近黑色
在这里插入图片描述
在这里插入图片描述

15.5 颜色函数saturate与desaturate

saturate 增加颜色的纯度,也就是饱和度
desaturate 减少颜色的纯度。
在这里插入图片描述
在这里插入图片描述

15.6 颜色函数 opacify与transparentize 透明度

opacify:增加不透明度
opacify语法:opacify(要设置的对象,增加多少不透明度)
transparentize:减少不透明度
transparentize语法:基本同上
在这里插入图片描述
在这里插入图片描述

15.7 list 列表类型数据

sass里边的list可以使用空格、逗号、括号()、等分隔开
例如:

border:1px solid #000;
font-family: Courier, Lucida Console", monospace
padding:(5px 10px)(5px 0)

列表里边可以包含其他列表,比如:
padding里边是一个列表包含了两个列表。

padding:5px 10px,5px 0

15.8 列表函数

15.8.1 length() 返回列表项目个数

length()用于返回列表里有多少个项目:
例如:

PS F:\Node.js\Node_project\study> sass -i
>> length(5px 10px)
2
>> length(5px 10px 5px 0)
4
15.8.2 nth() 得到对应序号里边的数据

nth()用于得到指定位置的列表项目

PS F:\Node.js\Node_project\study> sass -i
>> nth(5px 10px,2)
10px
15.8.3 index()判断指定项目在列表里的位置

index() 用于判断指定项目在列表里的位置

>> index(1px solid red,solid)
2
15.8.4 append() 向列表追加项目
>> append(5px 10px,5px)
(5px 10px 5px)

这个函数还有第三个参数,用于指定列表的分隔符
例如:

>> append(5px 10px,5px,comma)
(5px, 10px, 5px)
15.8.5 join() 组合列表

join()用于组合列表

>> join(5px 10px,5px 5px)
(5px 10px 5px 5px)

这个函数也有第三个参数,用于指定分隔符 例如:

>> join(5px 10px,5px 5px,comma)
(5px, 10px, 5px, 5px)

十六、Map与相关函数

Map就是列表项目带名字的列表,例如:
$map: (key1: valuel, key2: value2, key3: value3)

16.1定义Map类型数据

PS F:\Node.js\Node_project\ninghao-sass> sass -i
>> $colors:(light:#ffffff,dark:#000000)
(light: #ffffff, dark: #000000)

用在列表上边的函数同样可以处理Map类型的数据。
例如:
length() 查看变量中有,几个变量

>> length($colors)
2

16.2 map-get(参数1,参数2) 可以根据键来得到值

例如:

>> map-get($colors,dark)
#000000

16.3 map-keys(参数1) 返回对象当中的所有key

例如:

>> map-keys($colors)
("light", "dark")

16.4 map-values(参数1) 返回对象当中所有的value

例如:

>> map-values($colors)
(#ffffff, #000000)

16.5 map-has-key(参数1,参数2) 判断对象当中是否有指定的key

例如:

>> map-has-key($colors,test)
false
>> map-has-key($colors,dark)
true

16.6map-merge(参数1,参数2) 把两个Map合并到一起

>> map-merge($colors,(light-gray:#e5e5e5))
(light: #ffffff, dark: #000000, light-gray: #e5e5e5)

合并之后我们可以把这个变量交给 $colors :

>> $colors:map-merge($colors,(light-gray:#e5e5e5))
(light: #ffffff, dark: #000000, light-gray: #e5e5e5)
>> $colors
(light: #ffffff, dark: #000000, light-gray: #e5e5e5)
>>

16.7 map-remove(参数1,参数2,…) 移除指定的键值对

例如:

>> map-remove($colors,light,light-gray)
(dark: #000000)
>>

注意:移除过后很少 $colors并没有减少,例如:

>> $colors
(light: #ffffff, dark: #000000, light-gray: #e5e5e5)
>> map-remove($colors,light,light-gray)
(dark: #000000)
>> $colors
(light: #ffffff, dark: #000000, light-gray: #e5e5e5)

可以看到$colors 还是原来的3个键值对
如果需要真正的移除需要对它赋值:
例如:

>> $colors
(light: #ffffff, dark: #000000, light-gray: #e5e5e5)
>> $colors:map-remove($colors,light,light-gray)
(dark: #000000)
>> $colors
(dark: #000000)

十七、boolean 布尔值

取值: true false

PS F:\Node.js\Node_project\ninghao-sass> sass -i
>> 5px > 3px
true
>> 5px > 10px
false
>> (5px < 10px) and (5px > 6px)
false
>> (5px < 10px) and (5px < 6px)
true
>> (5px < 10px) or (5px > 6px)
true

>> 5px > 3px
true
>> not (5px > 3px)
false
>> not (5px < 3px)
true

十八、Interpolation 可以把一个值插入到另一个值里边

简单点来说,就是在 特殊的地方(注释、属性名)等地方使用变量。
语法: #{} 花括号中间放变量名即可。
例如:
在这里插入图片描述

十九、流程控制语句

19.1 @if 判断

例如:
在这里插入图片描述

19.2 @for 循环

在Sass中,我们可以使用“@for”来实现循环操作。其中,Sass中的@for循环有2种方式。
语法:

方式1:@for $i from 开始值 through 结束值
方式2:@for $i from 开始值 to 结束值

说明:

这2种方式是相似的,唯一的区别是:方式1包括结束值,方式2不包括结束值。
其中“开始值”和“结束值”都是正整数。

举例:
在这里插入图片描述

分析:
在这里插入图片描述

如果将“@for $i from 1 through 3”改为“@for $i from 1 to 3”,则编译出来的CSS代码如下:

19.3 @each in 循环

就是去遍历一个列表,然后从列表中取出对应值;
在这里插入图片描述

19.4 @while 循环

只要条件为真,就执行语句体
在这里插入图片描述

二十、用户自定义函数

语法:
@function 函数名称(参数1,参数2,…){

}

这里我们定义一个函数 color ,用于根据map的key返回map的value

React

01-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,渲染的挂载位置

【案例:实现多个元素嵌套显示】

02-react脚手架

React脚手架意义

  1. 脚手架是开发现代Web应用的必备。
  2. 充分利用Webpack、 Babel、 ESLint等I具辅助项目开发。
  3. 零配置,无需手动配置繁琐的工具即可使用。
  4. 关注业务,而不是工具配置。

使用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基础阶段总结

  1. React是构建用户界面的JavaScript库

  2. 使用react时,推荐使用脚手架方式

  3. 初始化项目命令: npx create-react-app my-app

  4. 启动项目命令: 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语法

  1. JSX不是标准的ECMAScript语法,它是ECMAScript的语法扩展

  2. 需要使用babel编译处理后,才能在浏览器环境中使用。

  3. create-react-app脚手架中已经默认有该配置,无需手动配置。

  4. 编译JSX语法的包为: @babel/preset-react。

JSX的注意点

  1. React元素的属性名使用驼峰命名法
  2. 特殊属性名: class -> className、for -> htmlFor、tabindex -> tabIndex
  3. 没有子节点的React元素可以用 /> 结束
  4. 推荐:使用小括号包裹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阶段总结

  1. JSX React的核心内容。
  2. JSX 示在JS代码中写HTML结构,是React声明式的体现。
  3. 使用JSX配合嵌入的JS表达式、条件渲染、列表渲染,可以描述任意UI结构。
  4. 推荐使用className的方式给JSX添加样式。
  5. 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路由基础总结

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

埃菲尔上de铁塔梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值