JavaScript+react笔记

开始一个工程

安装 脚手架 及工具

下载node.js并安装 node -v检查是否安装成功

npm install create-react-app -g

安装yarn

npm install -g yarn
yarn --version

Yarn 淘宝源安装

yarn config set registry https://registry.npm.taobao.org -g
yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g

如果出现 ‘yarn’ 不是内部或外部命令,也不是可运行的程序 或批处理文件

  1. 卸载 npm uninstall yarn -g

  2. 安装 npm install yarn (最好不要用别的安装命令,会没效果)

  3. 添加环境变量:系统变量path添加 C:\Users\bokeyuan\node_modules\yarn\bin

  4. 重新打开cmd执行:yarn -v 查看版本号

创建项目 myapp

CMD 到工程目录下 利用脚手架 创建

create-react-app myapp # 项目名不能有大写

src 目录下

index.js (必须叫index.js 否者静态目录寻找不到)

所有 其他 文件可以删除

运行 react 的服务器

npm start

生成的文件结果及作用

|-- README.mad    		 使用说明
|-- node_modules   		 所有的依赖文件
|-- package-lock.json 	   锁定安装时的包版本号,保证团队一直
|-- package.json   
|-- public      	    静态公共目录
|-- src				    开发用的源代码目录

其他电脑配置相同环境可以复制除 node_modules 意外的文件

用一下命令重建环境

npm i

打包项目

构建项目

npm run build

安装 serve

npm install serve -g

运行 serve

serve build

运行 serve 报错 的解决方案

报错信息:无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统中禁止执行脚本

原因分析:禁止执行脚本,那就打开权限执行脚本嘛

解决方案:

  1. 打开 powerShell 用管理员身份运行 (Win + X)
  2. 输入命令: set-ExecutionPolicy RemoteSigned
  3. 输入A

# 搭配django

build 文件下 static 放入 Django的static

其他文件 放入 Django 的templates 文件夹夏

正常调用index.html

# 引入 bootstrap

npm install bootstrap --save

在index.js引入Bootstrap

import 'bootstrap/dist/css/bootstrap.min.css'

流程控制

循环遍历

for 循环

//循环遍历 
for(var i; i < v1.length; i++){
    // i = 0/1/2
}
//快速 循环遍历 
var v1 = [11,22,33]
for(var i in v1){
    // i = 0/1/2
}

map 循环

// 第一i中写法
{ arr.map((item, index) => { return
{item}
}) }
// 第二种写法 var str = arr.map((item, index) => { return
{item}
}) ReactDOM.render(
{str}
, document.getElementById("root2") ) // 第三种写法 var str=[]; for(let i=0;i{arr[i]}
) } ReactDOM.render( str, document.getElementById("root3") )

forEach 循环

// 用法一
arr.forEach((item, index) => {
   ......
})

// 用法二
arr.forEach((item, index) => {
    return 
{item}
})

遍历数组用map和forEach的区别

1.map函数返回一个新的数组,在map的回调函数里,迭代每一项的时候也必须有返回值。

2.forEach 没有返回值。

map方法处理数据之后会返回一个新的数组,同时不会改变原数组的值;

如果数组为空则无法进行遍历,所以要对数组做非空校验。

if 条件语句

if (条件) {
    执行语句1
}else if (条件){
    执行语句2
}else{
    执行语句3
}

三元运算符

条件表达式 ? 真就执行表达式1:假就执行表达式2
//三元运算符 的变体
条件表达式 && 真就执行表达式1

数据

数据类型

查看数据类型

typeof "john"

数据类型转换

// 转换为字符串类型
String(123) 
(100 + 23).toString()
// 字符串装换为数字类型
Number("3.14") 

更多:https://www.runoob.com/js/js-type-conversion.html

提取数字

1.前面带数字,后面非数字,可以直接用parseFloat()函数:

var num1 = parseFloat("2.89元"); //num1 : 2.89

2.像"生于1999年"这样字符串中只含有一个整型数值的字符串,直接使用正则表达式将数字的字符删除掉就行

var str1 = '生于1999年';
var num1 = str1.replace(/[^\d]/g,' ');

3.对于字符串中含有多数值,使用字符串的match方法,通过正则表达式提取字符串的所有数字(包含整数和小数):

var str = '大米:2.57斤/元,白菜:3.65元/斤';
var arr = str.match(/\d+(.\d+)?/g);    // arr: ["2.75","3.65"]

[正则表达式] 提取字符串的所有数字

1、不考虑小数

此时可以使用正则表达式(/\d+/g)来从字符串中提取数字

使用正则表达式(/\d+/g)来从字符串中提取数字
var str = '123sdfsdf456sdffs789'
var numArr = str.match(/\d+/g)
// 直接输出
console.log("直接输出:"+numArr) // => ["123", "456", "789"]
// 也可以把数字拼接起来
console.log("拼接后输出:"+numArr.join('')) // => 123456789

2、考虑小数

此时可以使用正则表达式(/\d+.\d+/g)来从字符串中提取数字

var str = '123.456sdfsdf456.789'
var numArr = str.match(/\d+\.\d+/g)
console.log(numArr) / /=> ["123.456", "456.789"]

变量

var name = "世界"
var v1 = name.length://获取字符串长度
var v2 = name.[0];//利用索引获取字符串中的字符
var v3 = name.trim(); //去除空白
var v4 = name.substring(0,2) //字符串切片 (前取后不取)

案例: 跑马灯

function s() {
    var n = document.getElementById('text') //利用ID查找 获取 标签 保存到n
    var x = n.innerText //  标签对象n 的字符串属性的值 保存到x
    n.innerText = x.substring(1, n.length) + x[0] //改变字符串 后 赋值给 n 的 字符串属性
    console.log("控制台显示x:",x)
}
setInterval(s, 200) //利用间隔函数 设置 每秒的运行次数(FPS) 

数组

创建数组

//定义列表 
var v1 = [11,22,33] 
 //用 Array函数构建列表
var v2 = Array([11,22,33])
//生成 带10个空元素的 数组
var b = new Array(10)

修改值

a[0] = '你好'

追加

返回值是列表长度

尾部追加

var l1 = a.push('奥德赛')

在列表的 头部 追加

a.unshift('达到') 

删除

返回值是列表长度

删除最后一个元素

var l2 = a.pop()

删除头部

a.shift()

合并数组

返回新列表

var a = [0, 0, 0, 0, 0, 0, 0]
var b = [1, 1, 1]
var c = a.concat(b, 3, true, "字符串")

提取数组

提取 (下表为0~3的元素) 数组

返回值一个新数组

var c = a.slice(0, 3)

splice 根据 索引 操作

索引 (下表为1的位置开始 ) 追加 元素

a.splice(1,0,'大大')

索引 (下表为e的位置开始 ) 删除 1个元素

a.splice(e,1) 

合并字符串 join

合并字符串 (默认以 , 分隔)

var fruits = ["Banana", "Orange", "Apple", "Mango"]
var x = fruits.join()
console.log(x)

https://www.runoob.com/jsref/jsref-obj-array.html

数字 字符串 互换 提取

import React from 'react';

const App2 = () => {

    //字符串转 数字
    var a = Number("023123")
    // 数字转字符串
    var b = String(111111)
    //提取 字符串 中的数字
    var c = parseInt("102元")
    const xxx = () => {
        console.log('字符串转为数字 a:', a)
        console.log('数字转换为字符串 b:', b)
        console.log('提取字符串中的数字 c:', c)
    }

    return (
        
); } export default App2;

更多操作 方法

https://www.runoob.com/js/js-obj-array.html

数组 的 引用

对象 块

定义

 info = {
     'name':'吴博文',
     'age': 10
 }
// JS中的对象(字典) key(键) 可以不加引号
 info = {
     name:'吴博文',
     age: 10
 }

获取 更新 删除 值

info['age'] = 11
//简便写法
info.age = 11
//删除
delete info['name']
delete info.name

对象的for 遍历

for (var i in info){
    i // name/age  i的值就是对象(字典)的key(键值)
    x = info[i] //获取值
}

函数

https://www.runoob.com/jsref/jsref-obj-math.html

function aaaa(){
    ...
}
    
aaa()

MATH 函数

生成 随机数

//返回 0 ~ 1 之间的随机数
Math.random()
//返回数的平方根
Math.sqrt(x)
// 返回 x 的 y 次幂
Math.pow(x, y)
//返回 x,y,z,...,n中的最低值
Math.min(x,y,z,...,n)
//四舍五入
Math.round()

BOM DOM

控制台打印

var a = "也可以打印变量"
console.log("这段文字会在控制台显示",a)

提示框

基础提示框

    const info = () => {
        window.alert("提示框")
    }

带 确定和取消的提示框 返回布尔值

    const info = () => {
        var res = window.confirm("是否同意")
        console.log(res)
    }

带 输入内容的提示框 返回驶入内容

    const info = () => {
        //第二个参数为默认值
        var res = window.prompt("请输入内容", 100)
        console.log(res)
    }

打开一个新的页面

    const info = () => {
        window.open("https://www.baidu.com/")
    }

页面历史记录

            
            
            

获取url

    const info = () => {
        alert(window.location)
    }

location 的属性和方法…

页面加载完成后 onload

window.onload = function () {
  alert("页面完成")
}

案例:ReactDOM 的用法

//导入  React 核心包 解释jsx语法
import React from "react"
// 导入 React虚拟DOM  把组件渲染到页面
import ReactDOM from "react-dom"
//利用 js 的document 操作选择 ID 为root的标签  在它的列表中添加 
ReactDOM.render(
    

利用ReactDOM渲染HTML标签

, document.getElementById("root") )

案例:ES6 类的继承

class T {
    //类的初始化函数
    constructor() {
        ;
    }
    // 类的方法函数
    fuc_A() {
        console.log("这个信息来自父类~~~~")
    }
}
//定义一个类C 继承 T类 
class C extends T {
    //定义自己的方法函数
    fuc_B() {
        console.log("这个消息来自己子类~~~~~")
    }
}
//创建 一个实例 
var a = new C()
//调用 实例的方法
a.fuc_A()
a.fuc_B()

事件监听器

常用CSS (jsx写法)

css-in-js

https://blog.csdn.net/qq_45677671/article/details/117332040?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165336194316782425147803%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=165336194316782425147803&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-117332040-null-null.142v10control,157v8control&utm_term=css+in+js&spm=1018.2226.3001.4187

npm i -S styled-components

案例:内联样式测试

import React, { Component } from 'react';
// 导入样式组件
import styled from 'styled-components';

class App2 extends Component {
    aa() {
        console.log("ddadf")
    }
    render() {
        return (
            
内部文件写法
); } } export default App2; // 样式 const MDIV = styled.div` font-size: 50px; color: red; background-color: red; `

自身定位

定位模式

position :'static',

HTML 元素的默认值,即没有定位,遵循正常的文档流对象

静态定位的元素不会受到 top, bottom, left, right影响

position :'fixed ',

元素的位置相对于浏览器窗口是固定位置

即使窗口是滚动的它也不会移动

position :'relative',

相对定位元素的定位是相对其正常位置

position :'absolute',

绝对定位的元素的位置相对于最近的已定位父元素

如果元素没有已定位的父元素,那么它的位置相对于

定位模式

position :'sticky ',

sticky 英文字面意思是粘,粘贴,所以可以把它称之为粘性定位。

position: sticky; 基于用户的滚动位置来定位。

粘性定位的元素是依赖于用户的滚动,在 position:relativeposition:fixed 定位之间切换。

它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。

元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。

这个特定阈值指的是 top, right, bottom 或 left 之一,换言之,指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。

定位坐标

right:'100px',

left:'100px',

top:'100px',

bottom: '100px',

更多:https://www.runoob.com/css/css-positioning.html

相对定位

子元素对齐

//子元素 居中对齐
display: 'block',
margin:  'auto',
// 文本(子元素) 横向居中对齐 或者 左右对齐
textAlign: 'center',
textAlign: 'left',
textAlign: 'right',
//每一行被展开为宽度相等,左,右外边距是对齐(如杂志和报纸)
textAlign: 'justify',
// 文本(子元素) 垂直居中对齐
padding: '70px 0',

//子元素的行高设置
lineHeight: '100px',

更多:https://www.runoob.com/css/css-align.html

浮动

 // 左浮动
float:'left',
 // 右浮动
float:'right',
 // 无浮动
float:'none',
 // 中心浮动
float:'inherit',

//清除浮动
clear:'both',

文本

// 字体颜色
color:'blue',

// 字体大小
fontSize:'2.5em',
fontSize:'100%',


// 文本修饰
    //清除默认 文本修饰
    texDecoration:'none',
	// 上线
    textDecoration:'overline ',
	// 删除线
    textDecoration:'line-through',
	// 下线
    textDecoration: 'underline',

https://www.runoob.com/css/css-text.html

https://www.runoob.com/css/css-font.html

背景

// 背景颜色
backgroundColor:'red',

https://www.runoob.com/css/css-background.html

盒模型

// 清除边框外的区域,外边距是透明的
margin: '25px',
// 围绕在内边距和内容外的边框
border: '25px solid green',
// 清除内容周围的区域,内边距是透明的
padding: '25px',
// 盒子的内容,显示文本和图像

// Content(内容) - 盒子的内容,显示文本和图像

margin 外边距 详细

https://www.runoob.com/css/css-margin.html

border 边框 详细

https://www.runoob.com/css/css-border.html

padding 填充 详细

https://www.runoob.com/css/css-padding.html

盒模型详细:https://www.runoob.com/css/css-boxmodel.html

Bootstrap5

菜鸟教程 https://www.runoob.com/bootstrap5/bootstrap5-tutorial.html

仿官方中文文档 https://v5.bootcss.com/

组件

组件库

PC版 https://ant.design/docs/react/introduce-cn

手机版https://mobile.ant.design/zh

[Ant Design] 组件库

https://ant.design/components/button-cn/

import React from "react"
import ReactDOM from "react-dom"
//导入组件  首字母必须大写
import T from "./01-base/01-class"
//吧组件添加到 目标中
ReactDOM.render(
    // 可以单标签 也可以双标签
    
    document.getElementById("root")
)

类 组件

vscode 快速创建react 类组件 rcc

// 定义类
class Runoob {
  constructor(name, year) {
    this.name = name;
    this.year = year;
  }
  age() {
    let date = new Date();
    return date.getFullYear() - this.year;
  }
}
// 实例化 类
let runoob = new Runoob("菜鸟教程", 2018)

函数式 组件

普通函数

import React from "react"
//定义函数组件 首字母必须大写
function App() {
    //返回值
    return (
        

函数组件返回的信息

) } //实例化 组件 export default App

箭头函数

vscode 快速创建react 函数组件 rfc

import React from "react"
//箭头函数
const Bpp = () => 

箭头函数送来的信息~~~~~

//导出 箭头函数 export default Bpp

嵌套

自定义标签只能嵌套在 函数或者类组件定义中

import React from "react"
//箭头函数1
const Bpp1 = () => 

箭头函数1送来的信息~~~~~

//箭头函数2 const Bpp2 = () =>

箭头函数送2来的信息~~~~~

//箭头函数3 桥套自定义函数 const App = () =>
//导出 组件 App export default App

插槽

使用 this.props.children 定义插槽

import React, { Component } from 'react'

class App2 extends Component {
    render() {
        return (
            
        );
    }
}

export default App2

class A extends Component {
    render() {
        return (
            

这个是第一个子组件

{this.props.children} {/* 多个插槽最少需要两个标签的使用*/} {/* {this.props.children[0]} {this.props.children[1]} {this.props.children[1]} */}
); } } class B extends Component { render() { return (

第二个组件放在了插槽中

); } }

表达式

import React from "react"

const name = '吴博文'
const age = 10
const App = () => 
{/* 字符串运算 */}
{"年龄是:" + 10}
{/* 字符串加变量 */}
{"名字是:" + name}
{/* 数字运算 */}
{20 + 10}
{/* 数字和變量运算 */}
{age + 10}
{/* 三目运算符 */}
{10 > 20 ? "对" : "错"}
//导出 组件 App export default App

样式

外联样式 || 内敛样式 || 行内样式

import React from "react"
import '../css/a.css'
// 导入css 模块

 定义样式变量 属性名必须改成小驼峰写法
var a = {
    background: 'red',
    fontSize: '50px'
}
//定义组件
const App = () => 
这个组件使用的是内联样式(React官方推荐)
这个组件使用了行内样式(React官方推荐)
这个组件使用外联样式
//导出 组件 App export default App

a.css

.a {
    background-color: rgb(149, 149, 186);
    font-size: 50px;
}

行内 字符串

单个字符串

demo div>

多个字符串 推荐

<div className={`content ${this.state.isActive?"active":null}`}>
    demo
div>

其他写法: 数组转化

demo div>

特殊功能组件

二维码读取

https://blog.csdn.net/weixin_43827462/article/details/119350721

获取

this 和 evt

this 指向调用它的实例对象

evt 指向 触发本函数 的实例(按钮)

import React, { Component } from 'react'

class App extends Component {
    a = '属性A'
    // 箭头函数中的this指向实例对象 App
    //  e 获取对象 给 函数体内部处理
    add_1 = (e) => {
        console.log("箭头函数1 调用类属性A:", this.a, e.target)
    }
    render() {
        return (
            
{/* 点击 执行箭头函数 调用实例化对象的 add_1 (可以传递参数) */} {/* e 获取对象(button对象本身) 传递进 函数内部 */}
); } } export default App

引用 ref

创建一个引用对象来操作标签

案例:获取输入框中的值

import React, { Component } from 'react'

class App extends Component {
    // 创建一个 ref 对象
    myRef = React.createRef()
    add_1 = () => {
        //  调用 实例化对象 中的 对象myRef 的字典current中的value值
        console.log("调用的标签的值是:", this.myRef.current.value)
    }
    render() {
        return (
            
{/* 绑定 ref对象 到 标签 */}
); } } export default App

案例:点击按钮 盒子变色

import React, { Component } from 'react';

class App extends Component {
    //创建一个引用
    divRef = React.createRef()
    myStyle = {
        backgroundColor: 'red',
        width: '100px',
        height: '100px',
        position: 'fixed',
        left: 200,
        top: 200
    }

    bianLan = () => {
        this.divRef.current.style.backgroundColor = 'blue'
    }

    bianHong = () => {
        this.divRef.current.style.backgroundColor = 'red'
    }

    render() {
        return (
            
{/* 设置 引用指向 */}
); } } export default App;

状态

类组件 状态的变化会刷新 render函数

函数组件中 状态的变化会刷新 整个函数

案例:收藏

利用 setState 间接修改 state 状态

rander函数 会等 setState 更新完状态有才会执行后面的代码

setState 不能放在rander函数中 否则会造成死循环

import React, { Component } from 'react'

class App extends Component {
    state = {
        at: 1
    }
    stc() {
        this.setState({ at: !this.state.at })
        if (this.state.at) {
            console.log("这里是收藏的逻辑~~~")
        } else {
            console.log("这里是不收藏的逻辑~~~")
        }
    }
    render() {
        return (
            
{/* 新建一个按钮 并且绑定触发事件 */}
) } } export default App

案例: 备忘录 (map)

import React, { Component } from 'react'


class App extends Component {

    //状态
    state = {
        list: [
            { ID: 1, V: 'aaa', ax: false },
            { ID: 2, V: 'bbb', ax: false },
            { ID: 3, V: 'ccc', ax: false },
        ],
        value: "初始值",
    }

    //选择框状态 更新
    boxchange = (index) => {
        let newlist = [...this.state.list]
        newlist[index].ax = !this.state.list[index].ax
        this.setState({
            list: newlist
        })
    }

    //文本框状态 更新
    mychange = (e) => {
        this.setState({
            value: e.target.value
        })
    }

    //添加 标签
    myadd = () => {
        //concat 展开列表
        let newlist = this.state.list.concat()
        // list.push(n) 给列表末尾添加一个元素 n
        newlist.push({
            ID: Math.random(),
            V: this.state.value,
            ax: false,
        })
        this.setState({
            list: newlist,
            value: ""
        })
    }
    //删除 标签
    mydel = (e) => {
        // ... 展开列表
        let newlist = [...this.state.list]
        // splice(e,1,n) 从e到n 每隔1个 删除
        newlist.splice(e, 1)
        this.setState({
            list: newlist
        })
    }

    render() {
        return (
            
{/* 输入框数据更新 */} this.mychange(event)} type="text" value={this.state.value} /> {/* 点击 触发函数 添加标签*/} {/* 判断列表是否为空 */}

{this.state.list.length === 0 ? "列表空了~~~~" : ""}

{/* map循环遍历 */} {this.state.list.map((item, index) =>
  • {/* 选择框 状态更新 */} this.boxchange(index)} type="checkbox" checked={item.ax} /> {/* 状态 控制 行内样式 */} {item.V} {/* 点击 触发喊出 删除标签 */}
  • )}
    ); } } export default App

    案例:动态选择

    import React, { Component } from 'react';
    import App1 from "./app01"
    import App2 from "./app02"
    import App3 from "./app03"
    
    class App extends Component {
        state = { a: '0' }
        sc = (e) => {
            this.setState({
                a: e.target.id
            })
        }
        render() {
            return (
                
    this.sc(e)}>页面一
    this.sc(e)}>页面二
    this.sc(e)}>页面三
    {this.state.a === '1' && } {this.state.a === '2' && } {this.state.a === '3' && }
    ); } } export default App;

    富文本展示 (解析HTML代码)

    渲染

    条件渲染

    案例:同不同意

    import React, { Component } from 'react';
    
    class App2 extends Component {
        state = {
            act: false
        }
        
        // 回调函数 
        aaa = () => {
            this.setState({ act: !this.state.act })
        }
    
        // 条件渲染
        abc = () => {
            if (this.state.act) {
                return 

    同意

    } else { return

    不同意

    } } render() { return (
    {this.abc()}
    ); } } export default App2;

    案例:每秒更新状态(条件渲染)

    import React, { Component } from 'react';
    
    class App2 extends Component {
        state = {
            act: false
        }
    
        componentDidMount() {
            setTimeout(() => this.setState({ act: !this.state.act }), 1000)
        }
        componentDidUpdate() {
            setTimeout(() => this.setState({ act: !this.state.act }), 1000)
        }
    
        render() {
            if (this.state.act) {
                return 

    同意

    } else { return

    不同意

    } } } export default App2;

    案例:同不同意(三元运算符)

    import React, { Component } from 'react';
    
    class App2 extends Component {
        state = {
            act: false
        }
    
        componentDidMount() {
            setTimeout(() => this.setState({ act: !this.state.act }), 1000)
        }
        componentDidUpdate() {
            setTimeout(() => this.setState({ act: !this.state.act }), 1000)
        }
    
        render() {
            return (
                
    {this.state.act ? "同意" : "不同意"}
    ); } } export default App2;

    案例:同不同意(逻辑运算符)

    import React, { Component } from 'react';
    
    class App2 extends Component {
        state = {
            act: false
        }
    
        componentDidMount() {
            setTimeout(() => this.setState({ act: !this.state.act }), 1000)
        }
        componentDidUpdate() {
            setTimeout(() => this.setState({ act: !this.state.act }), 1000)
        }
    
        render() {
            return (
                
    {this.state.act && "不同意"} {!this.state.act && "同意"}
    ); } } export default App2;

    列表渲染map

    尽量避免使用 index 设置 key

    案例: 批量创建标签

    import React, { Component } from 'react';
    
    class App2 extends Component {
        state = {
            list: [
                { ID: 1, name: "夏红", age: 21, },
                { ID: 2, name: "冯绍峰", age: 25, },
                { ID: 3, name: "大法师", age: 20, },
            ]
        }
    
        // 修改状态(删除第i项)
        del = (i) => {
            let temp_list = [...this.state.list]
            temp_list.splice(i, 1)
            this.setState({ list: temp_list })
        }
    
        render() {
            return (
                
    {this.state.list.map((item, index) =>
    {/* 遍历 输出内容 */}
    {item.name}
    {item.age}
    {/* 点击 触发回调函数 传入下标 */}
    )}
    ); } } export default App2;

    属性

    属性的作用主要是接收数据

    获取属性列表 this.props

    app.js

    import React, { Component } from 'react';
    import App01 from './app01'
    class App extends Component {
        render() {
            return (
                
    {/* 设置属性 和属性值 */}
    ); } } export default App;

    app01.js

    import React, { Component } from 'react';
    
    class App01 extends Component {
        render() {
            return (
                
    {/* 打印属性列表中的 某个属性的值 */}

    {this.props.biaoQian}

    ); } } export default App01;

    属性类型的验证 和 默认值

    app.js

    import React, { Component } from 'react'
    //导入属性验证模块
    import kerwinPropTypes from 'prop-types'
    
    class App01 extends Component {
        //属性 类型验证
        static propType = {
            biaoQian: kerwinPropTypes.string
        }
        //属性 设置默认值
        static defaultProps = {
            biaoQian: "页面"
        }
        render() {
            return (
                
    {/* 打印属性列表中的 某个属性的值 */}

    {this.props.biaoQian}

    ); } } export default App01

    {…obj} 展开列表

    通信

    单向控制

    案例: 受控组件

    利用状态控制组件

    import React, { Component } from 'react'
    
    class App extends Component {
        //初始化状态
        state = {
            value2: "",
        }
        x_ref = React.createRef()
    
        //传递数据
        shangChuan = () => {
            var v = this.x_ref.current.value
            if (v === ('')) {
                this.setState({
                    value2: "输入不能为空~~"
                })
            } else {
                this.setState({
                    value2: v
                })
            }
        }
        //重置
        chongZhi = () => {
            this.x_ref.current.value = ''
            this.setState({
                value2: ""
            })
        }
        render() {
            return (
                
    {/* 绑定 事件函数 */} {/* 调用子组件*/}
    ); } } export default App // ####### 可以分割成另一文件############################# class App01 extends Component { x_style = { height: "700px", width: "500px", margin: '15px', padding: '10px', border: '5px solid red', } render() { return (
    {/* 打印属性列表中的 某个属性的值 */}

    这个框是子函数部分:

    {this.props.shuJu}

    ); } }

    父子组件通信

    使用属性 传递数据 和 函数

    import React, { Component } from 'react'
    
    class App extends Component {
        state = {
            a: false
        }
        kaiGuan = () => {
            this.setState({ a: !this.state.a })
        }
        render() {
            return (
                
    ); } } export default App // ####### 可以分割成另一文件############################# class App1 extends Component { render() { return (
    {/* 利用属性 执行 函数 */}

    {/* 历史属性 获取 数据 */} {this.props.xx ? "子组件显示事件" : ""}

    ); } }

    通过 REF 获取子组件的状态

    非父子通信

    发布订阅模式

    中心供应商模式(context)

    MOBX

    安装插件

    npm i mobx
    

    变量式 创建一个状态中心

    // store.js
    
    
    import { observable, configure, action } from 'mobx'
    
    // 开启严格模式
    configure({
        enforceActions: 'always'
    })
    // 创建
    const commonState = observable({
        score: 0,
        add_score(v) {
            this.score += v
        },
        change_score(v) {
            this.score = v
        },
    
    }, {
        change_score: action,
    })
    
    export default commonState;
    

    修改状态

    // temp.js
    
    
    import commonState from './store'
    import React, { Component } from 'react'
    import A from './A'
    
    // Temp
    export default class Temp extends Component {
        add = () => {
            // 修改 公共状态
            commonState.add_score(2)
        }
        render() {
            return (
                
    ) } }

    监听 并使用

    // A.js
    
    
    import React, { Component } from 'react'
    import commonState from './store'
    import { autorun } from 'mobx'
    
    // A
    export default class A extends Component {
        state = {
            A: 0,
        }
    
        componentDidMount() {
            // 创建一个监听器  (只有公共状体改变时才会触发回调函数)
            this.unAutorun = autorun(() => {
                console.log(commonState.score)
                // 使用 公共状体 修改自身状态
                this.setState({ A: commonState.score })
            })
        }
    
        componentWillUnmount() {
            // 销毁监听器
            this.unAutorun()
        }
        render() {
            return (
                
    {this.state.A}
    ) } }

    类方式 状态中心

    // store.js
    
    import { observable, computed, action, makeObservable } from 'mobx'
    
    
    class Store {
        constructor() {
            makeObservable(
                //指定目标
                this,
                //定义当前mobx类对象中的数据类型
                {
                    // 数据类
                    list: observable,
                    // 修改函数类
                    change: action,
                    // 获取类
                    total: computed,
                }
            )
        }
        list = []
    	//在类中,有一个getter方法,在使用的时候是一个数据
        get total() {
            return this.list.length;
        }
        change() {
            this.list.push(this.list.length);
        }
    }
    
    export default new Store();
    

    修改和 监听

    // temp.js
    
    import React, { Component } from 'react'
    import { autorun } from 'mobx'
    import Store from './store'
    
    
    setInterval(() => {
        Store.change()
    }, 2000)
    
    autorun(() => {
        console.log(Store.total)
    })
    
    
    // Temp
    export default class Temp extends Component {
        render() {
            return (
                
    ) } }

    https://www.cnblogs.com/cc-font/p/16046138.html

    runInAction()

    严格模式

    详细教程:https://www.bilibili.com/video/BV1dP4y1c7qd?p=105&spm_id_from=pageDriver

    插槽

    生命周期

    https://www.runoob.com/react/react-component-life-cycle.html

    生命周期图

    三个常用生命周期

    // 组件加载完成后 运行
    componentDidMount()  { console.log('组件加载完成')}
    //组件更新完成后 
    componentDidUpdate() { console.log('组件更新完成')}
    //组件将要卸载前
    componentWillUnmount() {console.log('组件将要卸载')}
    

    hooks 函数

    useState

    案例:显示状态值

    import React, { useState } from 'react';
    
    function Example2() {
    
        const [number, setNumber] = useState(0);
    
        const lazy1 = () => {
            // 获取点击按钮时的 state
            setNumber(number + 1);
        };
    
        const lazy2 = () => {
            // 每次执行时都会再去获取新的 state,而不是使用点击触发时的 state
            setNumber(number => number + 1);
        };
    
        return (
            

    {number}



    ); } export default Example2;

    案例:to do list

    import React, { useState } from 'react';
    
    const App = () => {
        const [data, setdata] = useState("")
        const [list, setlist] = useState([])
    
        const changeText = (e) => {
            setdata(e.target.value)
        }
    
        const addlist = () => {
            setlist([...list, data])
            setdata("")
        }
        const dellist = (index) => {
            console.log(index)
            var templist = [...list]
            templist.splice(index, 1)
            setlist(templist)
        }
    
        return (
            

    请输入带办事项

      { list.map((itme, index) =>
    • --- {itme}---
    • ) } {!list.length && "暂无代办事项"}
    ); } export default App;

    useEffect

    案例: 定时器

    import React, { useEffect, useState } from 'react'
    
    const A = () => {
    
        const [T, setT] = useState(1)
    
        useEffect(() => {
            const interval = setInterval(() => getCurrentTime(), 1000) // 定时器
            return () => {
                clearInterval(interval) // 销毁 
            }
        }, [T])
        //定时器的方法
        const getCurrentTime = () => {
            setT(T + 1)
        }
    
        const chongZhi = () => {
            setT(0)
        }
    
        return (
            

    {T}

    ) } export default A

    useRef

    需要获取另一个标签或者组件的属性信息时使用

    案例:点击按钮 盒子变色

    import React, { useRef } from 'react';
    
    const App = () => {
    	//创建 REF
        const divRef = useRef()
        const myStyle = {
            backgroundColor: 'red',
            width: '100px',
            height: '100px',
            position: 'fixed',
            left: 200,
            top: 200
        }
    
        const bianLan = () => {
            divRef.current.style.backgroundColor = 'blue'
        }
    
        const bianHong = () => {
            divRef.current.style.backgroundColor = 'red'
        }
        return (
            
    {/* 设置 引用指向 */}
    ); } export default App

    事件

    事件的详细说明

    https://www.runoob.com/jsref/dom-obj-event.html

    键盘事件

    keypress (键盘点击 按下并且弹起)

    keydown (键盘按下)

    keyup (键盘弹起)

    键盘事件详细说明 https://www.runoob.com/jsref/dom-obj-event.html

    键盘事件的对象属性

    //按下的键值 字符串 式
    window.event.key
    //按下的键值 数值 式
    window.event.keyCode
    //按下的键值 数值 式(区分大小写) 只能在keypress 模式下
    window.event.charCode
    

    案例 : 键盘事件

    import React, { Component } from 'react'
    
    class A extends Component {
        //添加全局事件
        componentDidMount() {
            document.addEventListener('keydown', this.onKeyDown)
        }
        // 销毁
        componentWillUnmount() {
            document.removeEventListener('keydown', this.onKeyDown)
        }
        //按键触发函数 直接获取到事件对象  window.event
        onKeyDown = (e) => {
            console.log(e)
            if (e.key === "1") {
                console.log("按下了1键")
            }
        }
        render() {
            return (
                
    ); } } export default A;

    案例 :函数式 键盘事件

    import React, { useEffect } from 'react';
    const A = () => {
        useEffect(() => {
            window.addEventListener('keydown', onKeyDown); // 添加全局事件
            return () => {
                window.removeEventListener('keydown', onKeyDown); // 销毁
            };
        }, [])
    
        // 键盘事件
        const onKeyDown = (e) => {
            console.log(e)
        }
    
        return (
            
    ) } export default A

    鼠标事件

    click (鼠标点击 按下并且弹起)

    mousemove(鼠标移动)

    mousedown(鼠标按下)

    mouseup(鼠标弹起)

    mouseover (鼠标移到猛哥元素上)

    mouseout(鼠标移开)

    更多鼠标事件https://www.runoob.com/jsref/dom-obj-event.html

    鼠标事件的对象属性

    鼠标可组合键盘快捷键

    // win 键
    window.event.metaKey 
    // shift 键
    window.event.shiftKey
    // alt 键
    window.event.altKey
    // ctl 键
    window.event.ctrlKey
    

    获取数据

    // 鼠标按下的是哪个键 1 左键 2右键 4中键
    window.event.buttons
    //点击 位置的 坐标(相对浏览器)
    window.event.clientX
    //点击 位置的 坐标(对象屏幕)
    window.event.screenX
    //点击到的标签的坐标
    window.event.offsetX
    

    获取点击目标

    //本次事件作用的 目标标签
    window.event.target
    

    案例 : 全局 鼠标点击

    import React, { Component } from 'react'
    
    class A extends Component {
        //添加全局事件
        componentDidMount() {
            document.addEventListener('click', this.onKeyDown)
        }
        // 销毁
        componentWillUnmount() {
            document.removeEventListener('click', this.onKeyDown)
        }
        //按键触发函数
        onKeyDown = (e) => {
            console.log(e.x, e.y)
        }
        render() {
            return (
                
    ); } } export default A;

    案例: 鼠标移动 并获取 坐标

    import React, { useState, useEffect } from 'react'
    
    
    const A = () => {
    
        const [my_x, setx] = useState(0)
        const [my_y, sety] = useState(0)
        const myStyle = {
            position: 'absolute',
            left: my_x,
            top: my_y,
            backgroundColor: 'red'
        }
    
        useEffect(() => {
            const interval = window.addEventListener('mousemove', handleMoveMouse)
            return () => {
                clearInterval(interval) // 销毁 
            }
        }, [])
        const handleMoveMouse = (e) => {
            setx(e.x)
            sety(e.y)
        }
        return (
            
    盒子
    ); } export default A;

    案例:鼠标拖尾

    
    import React, { Component } from 'react';
    
    class App extends Component {
    
        state = {
            list: [
                [101, 0],
                [102, 100],
                [103, 200],
                [104, 200],
                [105, 300],
                [106, 400],
                [107, 500],
                [108, 600],
                [109, 700]]
        }
        myStyle = {
            position: 'absolute',
            backgroundColor: 'red'
        }
    
        componentDidMount() {
            document.addEventListener('mousemove', this.handleMoveMouse)
        }
        // 销毁
        componentWillUnmount() {
            document.removeEventListener('mousemove', this.handleMoveMouse)
        }
        
        handleMoveMouse = (e) => {
            let b = [...this.state.list]
            b[0] = [e.x, e.y]
            for (var i = b.length - 1; i > 0; i--) {
                b[i] = b[i - 1]
            }
            this.setState({ list: b })
        }
        
        render() {
            return (
                
    { this.state.list.map( item =>
    盒子
    ) }
    ); } } export default App;

    案例:点击 变红移动

    import React, { useEffect } from 'react'
    
    const App2 = () => {
    
        const myStyle = {
            backgroundColor: 'blue',
            width: '100px',
            height: '100px',
            position: 'fixed',
            left: 200,
            top: 200
        }
    
        useEffect(() => {
            //添加 鼠标点击 监听事件 执行XXX函数
            window.addEventListener("click", xxx)
            return () => {
                //删除 鼠标点击 监听事件 和 XXX函数的调用
                window.removeEventListener("click", xxx)
            }
        }, [])
    
        const xxx = (e) => {
            //排除无ID的标签
            if (e.target.id) {
                e.target.style.backgroundColor = 'red'
                e.target.style.left = 0
            }
        }
    
        return (
    
            
    ) } export default App2;

    案例:全局鼠标拖拽

    import React, { Component } from 'react';
    
    class App extends Component {
        // 状态
        state = {
            status: false,
            dy: 0,
            dx: 0,
            id: "",
        }
        // 定义公共样式
        myStyle = {
            backgroundColor: 'red',
            width: '100px',
            height: '100px',
            position: 'fixed',
            left: 200,
            top: 200
        }
    
        // 开启事件监听
        componentDidMount() {
            window.addEventListener('mousedown', this.onMouseDown)
            window.addEventListener('mousemove', this.onMouseMove)
            window.addEventListener('mouseup', this.onMouseUp)
        }
    
        // 销毁
        componentWillUnmount() {
            window.removeEventListener('mousedown', this.onMouseDown)
            window.removeEventListener('mousemove', this.onMouseMove)
            window.removeEventListener('mouseup', this.onMouseUp)
        }
    
        // 开启跟随  保存 点击位置的坐标偏移值
        onMouseDown = (e) => {
            if (e.target.id === "") { return }
            console.log("点击到了ID为 ", e.target.id, " 的东西")
            this.setState({
                // e.offsetX === e.clientY - e.target.offsetTop
                // 也就是鼠标 在标签内部的坐标(偏移)
                dx: e.offsetX,
                dy: e.offsetY,
                status: true,
                id: e.target.id
            })
        }
    
        // 跟随 鼠标 
        onMouseMove = (e) => {
            if (this.state.status) {
                // 坐标数据 偏移值修正
                var ma_x = e.clientX - this.state.dx
                var ma_y = e.clientY - this.state.dy
                // 坐标数据 限制范围在浏览器中 innerWidth innerHeight 屏幕宽高
                if (ma_x < 0) { ma_x = 0 }
                if (ma_x > window.innerWidth - e.target.offsetWidth) {
                    ma_x = window.innerWidth - e.target.offsetWidth
                }
                if (ma_y < 0) { ma_y = 0 }
                if (ma_y > window.innerHeight - e.target.offsetHeight) {
                    ma_y = window.innerHeight - e.target.offsetHeight
                }
                // 坐标数据 传递给样式
                e.target.style.top = `${ma_y}px`
                e.target.style.left = `${ma_x}px`
            }
    
        }
    
        // 关闭跟随
        onMouseUp = () => {
            this.setState({
                status: false,
            })
        }
    
        render() {
            return (
                
    ); } } export default App;

    案例:鼠标 吸附拖拽

    import React, { useState } from 'react'
    
    const C = () => {
        const [ID, setID] = useState("xxx")
        const dr = {
            width: '100px',
            height: '150px',
            margin: '15px',
            padding: '10px',
            border: '1px solid #aaaaaa',
        }
        //所以想让一个元素可放置,需要重写 ondragover 
        const dragover = (e) => {
            e.preventDefault()
        }
    
        //有一个对象 dataTransfer 可以用来存储拖拽数据
        const start = (e) => {
            setID(e.target.id)
        }
        //在 ondrop 获取到这个值 利用ID吧 被拖动标签加入列表 把被拖拽元素的 id 存入  e.dataTransfer 
        const ondrop = (e) => {
            e.preventDefault()
            e.target.append(document.getElementById(ID))
        }
    
        return (
            

    拖动

    拖动

    拖动

    ); } export default C;

    触摸事件

    案例:触摸 拖拽

    import React, { useState } from 'react'
    
    const App = () => {
    
        const [dxy, setDxy] = useState({
            status: false,
            dy: 0,
            dx: 0,
        })
    
        const myStyle = {
            backgroundColor: 'red',
            width: '100px',
            height: '100px',
            position: 'fixed',
            left: 200,
            top: 200
        }
        //开启跟随  保存 点击位置的坐标偏移值
        const Down = (e) => {
            setDxy({
                dy: e.touches[0].clientY - e.target.offsetTop,
                dx: e.touches[0].clientX - e.target.offsetLeft,
                status: true,
            })
        }
        //跟随 (利用偏移值修正)
        const Move = (e) => {
            if (dxy.status) {
                 // ${xxx} 把大括号中的内容转换为 字符串 
                e.target.style.top = `${e.touches[0].clientY - dxy.dy}px`
                e.target.style.left = `${e.touches[0].clientX - dxy.dx}px`
            }
        }
        //关闭跟随
        const Up = () => {
            setDxy({
                status: false,
            })
        }
    
        return (
            
    ) } export default App;

    计时器

    案例: 计时器 自动创建DIV

    import React, { useEffect, useState } from 'react';
    
    const App2 = () => {
    
        const [List, setList] = useState([])
        const [T, setT] = useState(new Date().toLocaleString());
    
        useEffect(() => {
            //设置定时器 每1000毫秒 执行一次函数
            const interval = setInterval(myadd, 1000)
            return () => {
                // 销毁 定时器
                clearInterval(interval)
            }
        }, [T])
        //添加列表项
        const myadd = () => {
            let newlist = [...List]
            newlist.push({
                ID: Math.random(),
                V: T,
                ax: false,
            })
            setList(newlist)
            setT(new Date().toLocaleString())
        }
        //根据列表 创建DIV
        const makeDiv = () => {
            return (List.map(item =>
                
    现在的时间是 : {item.V}
    )) } return (
    {makeDiv()}
    ); } export default App2;

    案例:手动控制的计时器 类

    import React, { Component } from 'react'
    
    class App extends Component {
    
        state = { a: 0 }
        timer = undefined
    
        record = () => {
            this.setState({ a: this.state.a + 1 })
        }
        // 开启计时器  先关闭计时器 防止开启多个
        timerStart = () => {
            clearInterval(this.timer)
            this.timer = setInterval(this.record, 1000)
        }
        // 关闭计时器
        timerStop = () => {
            clearInterval(this.timer)
        }
        // 重置计时器
        timerCZ = () => {
            clearInterval(this.timer)
            this.setState({ a: 0 })
        }
    
        render() {
            return (
                

    计时器:{this.state.a}

    ) } } export default App;

    案例:手动控制的计时器 函数

    import React, { useState, } from 'react'
    
    let timer = undefined
    
    
    const App = () => {
    
        const [ST, setST] = useState(0)
    
        //计时器 调用的函数
        const record = () => {
            //需要调用 e 更新数据  setST 本质是一个回调函数
            setST(e => e + 1)
        }
        //先关闭计时器 再开启计时器
        const timerStart = () => {
            clearInterval(timer)
            timer = setInterval(record, 100)
        }
        //关闭 计时器
        const timerStop = () => {
            clearInterval(timer)
        }
        //重置 计时器
        const timerCZ = () => {
            clearInterval(timer)
            setST(0)
        }
    
        return (
            

    计时器: {ST}

    ); } export default App

    案例:手动控制盒子移动 (无状态)

    import React, { useRef } from 'react'
    //初始化
    let a = 0
    let timer = undefined
    let myStyle = {
        backgroundColor: 'red',
        width: '100px',
        height: '100px',
        position: 'fixed',
        left: '0px',
        top: '500px'
    }
    
    
    const App = () => {
    
        const h1Ref = useRef()
    
        const record = () => {
            h1Ref.current.style.left = `${a}px`
            a += 1
        }
    
        const timerStart = () => {
            clearInterval(timer)
            timer = setInterval(record, 10)
        }
    
        const timerStop = () => {
            clearInterval(timer)
        }
    
        const timerCZ = () => {
            clearInterval(timer)
            a = 0
            h1Ref.current.style.left = `0px`
        }
    
        return (
            
    ) } export default App;
    一次 计时器
    myVar = setTimeout(function(){ alert("Hello"); }, 3000);
    // 清理 一次 计时器
    clearTimeout(myVar);
    

    事件对象的属性和方法

    https://www.runoob.com/jsref/dom-obj-event.html

    目标对象(target)的 属性

    console.log("高:", e.target.offsetHeight)
    console.log("宽:", e.target.offsetWidth)
    console.log("X:", e.target.offsetLeft)
    console.log("Y:", e.target.offsetTop)
    

    请求 数据

    类组件中使用的方法

    axios 请求数据

    安装库

    npm i axios
    

    使用

    ComponentDidMount(){
        axios(this.baseUrl)
            .then(res => {
                const { goodlists
                } = res.data;
                this.setState({
                    list: goodlists
                })
            })
    
            .catch(err => {
                console.log(err)
            })
    }
    
    

    fetch 请求数据 推荐

    ComponentDidMount(){
        fetch(this.baseUrl)
            .then(res => res.json())
            .then((result) => {
                console.log(result)
                const { goodlists } = result
                this.setState({
                    list: goodlists
                })
            },
                (error) => {
                    console.log(error)
                }
            )
    }
    

    request 请求数据

    安装库

    npm install -s request
    npm install -s request-promise
    

    使用

    ComponentDidMount(){
        rp(this.baseUrl)
            .then(res => {
                const { goodlists } = JSON.parse(res)
                this.setState({
                    list: goodlists
                })
            })
            .catch(error => {
                console.log(error)
            })
    }
    

    路由

    安装路由

    npm install react-router-dom@5
    

    基本用法 ( /#/a)

    import React from 'react';
    import { Redirect } from 'react-router-dom';
    import { HashRouter, Route, Switch } from 'react-router-dom'
    import a from "./a"
    import b from "./b"
    import c from "./c"
    import notfand from "./notfand"
    
    const Luyou = () => {
        return (
            
    {/* 自上而下顺序 一个个匹配 */}
    ); } export default Luyou;

    重定向 Redirect (默认模糊匹配) 加属性 exact 精确匹配

     
    

    按钮绑定定向跳转页面函数

    import { Button, Row, Col } from 'antd'
    import React from "react"
    import { WindowsFilled, AppleFilled, AndroidFilled } from '@ant-design/icons'
    
    
    const Daohang = () => {
    
        // 跳转函数 编程式
        const link = () => {
            window.location.href = "#/c"
        }
    
        return (
            
        );
    }
    
    export default Daohang;
    

    音频 / 视频

    音频

    https://www.runoob.com/tags/tag-audio.html

    视频

    https://www.runoob.com/tags/tag-video.html

    const audio = this.audio.current;
    
    // 属性
    audio.paused // 是否暂停 - 用来判断当前播放状态 渲染按钮组件
    audio.duration // 歌曲时长 - 用来渲染进度条 READ ONlY
    audio.currentTime // 当前时间 - 用来渲染进度条 改变播放进度
    audio.volume // 音量 - 用于控制音量
     
    // 方法
    audio.play() // 播放
    audio.pause() // 暂停
    
    // 事件
    audio.onpause = () => {} // 暂停触发
    audio.onplay = () => {} // 播放触发
    audio.onended = () => {} // 结束触发 - 用于自动播放下一首
    audio.ontimeupdate = () => {} // 请特别注意这个方法:每250ms会调用一次,因为currentTime每250ms更新一次
    

    案例:播放器

    import React, { Component, createRef } from 'react';
    import fly from './aaa.mp3'
    
    // 音视频播放器
    class App2 extends Component {
    
        audioRef = createRef()
        // 开始
        audioPlay = () => {
            this.audioRef.current.play()
        }
        aa = () => {
            console.log(this.audioRef.current.volume)
        }
    
        //暂停
        audioPause = () => {
            this.audioRef.current.pause()
        }
    
        //停止
        audioStop = () => {
            this.audioRef.current.pause()
            this.audioRef.current.currentTime = 0
        }
    
        //重新播放
        audioRestart = () => {
            this.audioRef.current.currentTime = 0
            this.audioRef.current.play()
        }
    
        // 音量 +
        volumeAdd = () => {
            if (this.audioRef.current.volume >= 1) { return }
            this.audioRef.current.volume += 0.1
            console.log(this.audioRef.current.volume)
        }
        // 音量 -
        volumeReduce = () => {
            if (this.audioRef.current.volume <= 0.1) { return }
            this.audioRef.current.volume -= 0.1
            console.log(this.audioRef.current.volume)
        }
    
    
        render() {
            return (
                
    {/* src 音频地址 controls 显示界面*/}
    ); } } export default App2;

    教程

    react 教程

    react 全家桶 https://www.bilibili.com/video/BV1dP4y1c7qd?p=1

    https://www.bilibili.com/video/BV1wy4y1D7JT?p=37

    https://www.bilibili.com/video/BV1KS4y1h7jY?spm_id_from=333.337.search-card.all.click

    JavaScript 教程

    千锋教育JS全套教程500集_JavaScript零基础入门必备_Js核心技术精讲

    https://www.bilibili.com/video/BV11h411U7Sh?p=130&spm_id_from=pageDriver

    千锋教育JavaScript全套教程,10天JS零基础入门到精通(强烈推荐)

    https://www.bilibili.com/video/BV1pJ41157z8?spm_id_from=333.999.0.0

    vscode 及其插件

    ESLint 代码检查插件

    JS JSX Snippets

    自动重命名标签Auto Rename Tag

    不同的括号换上了不同的颜色 Bracket Pair Colorizer2

    检查单词拼写是否错误(支持英语)Code Spell Checker

    VSCODE通用插件+vue插件+react插件(2022版本)https://blog.csdn.net/happy81997/article/details/122995888

    综合练习

    打砖块

    import React, { Component } from 'react';
    
    class App extends Component {
    
        dr = {
            width: '400px',
            height: '600px',
            margin: '15px',
            padding: '10px',
            position: 'absolute ',
            border: '2px solid #aaaaaa',
            top: '50px',
        }
        dd = {
            position: 'absolute',
            right: '0px',
            width: '300px',
        }
        dr2 = {
            width: '50px',
            height: '50px',
            position: 'absolute   ',
            backgroundColor: 'red',
            borderRadius: '50%',
            bottom: '100px',
        }
        fangKuai = {
            width: '60px',
            height: '20px',
            margin: '2px',
            border: '2px solid green',
            float: 'left',
        }
        state = {
            x: 150
        }
        v = 0
        timer = undefined
    
    
        // 开始 使用计时器更新数据
        timerStart = () => {
            clearInterval(this.timer)
            this.timer = setInterval(() => this.setState({ x: this.state.x + this.v }), 5)
        }
        // 结束 关闭计时器
        timerStop = () => {
            clearInterval(this.timer)
        }
    
    
        moveStart = (e) => {
            // console.log(e)
            if (e.key === "ArrowRight") { this.v = 2 }
            if (e.key === "ArrowLeft") { this.v = -2 }
        }
    
        moveStop = () => {
            this.v = 0
        }
    
        componentDidMount() {
            document.addEventListener('keydown', this.moveStart)
            document.addEventListener('keyup', this.moveStop)
        }
        componentWillUnmount() {
            document.removeEventListener('keydown', this.moveStart)
            document.addEventListener('keyup', this.moveStop)
        }
    
    
        render() {
            return (
                
    {/* 按钮 */}
    {/* 小球 */}
    {/* 方块 */}
    ); } } export default App;

    触摸 打砖块

    import React, { Component, createRef } from 'react';
    
    // 数据中心
    let DATA = {
        // 小球的移动速度
        bobble_v: [10, 10],
        // 板子的移动速度 初始值
        block_v: [0, 0],
        // 板子的速度 控制 增加值
        control_v2: 10,
        //帧速率 每秒刷新率
        FPS: 60,
    }
    
    export default class App extends Component {
        chuangKou = {
            width: '400px',
            height: '800px',
            margin: '15px',
            padding: '10px',
            position: 'absolute ',
            border: '2px solid #aaaaaa',
            top: '100px',
        }
        banZiRef = createRef()
        xiaoQiuRef = createRef()
        pengZhuangRef = createRef()
        boxGroupRef = createRef()
        W = parseFloat(this.chuangKou.width)
        H = parseFloat(this.chuangKou.height)
        timer = undefined
    
        // 定义计数器 启动主时间序列
        yunXing = () => {
    
            // 板子 => 运行
            this.banZiRef.current.move(this.W)
    
            // 小球 => 运行
            this.xiaoQiuRef.current.move(this.H, this.W)
    
            // 碰撞检测  => 运行  
            //碰撞体和被配状态 需要有状态state = { x: 0, y:, 0 h: 0, w: 0 } 和 一个ref 
            this.pengZhuangRef.current.obj_polygonCollision_PASV(this.xiaoQiuRef.current, this.banZiRef.current)
    
            // 方块组 小球 碰撞检测 => 运行
            let Obj = {
                x: this.xiaoQiuRef.current.state.x,
                y: this.xiaoQiuRef.current.state.y,
                w: this.xiaoQiuRef.current.state.w,
                h: this.xiaoQiuRef.current.state.h,
            }
            this.boxGroupRef.current.boxGroup_Collision_PASV(Obj)
    
        }
    
        // 开启计时器 
        timerStart = () => {
            console.log("时间序列 启动 FPS:25")
            clearInterval(this.timer)
            this.timer = setInterval((this.yunXing), 1000 / DATA.FPS)
        }
        // 关闭计时器
        timerStop = () => {
            console.log("时间序列 关闭")
            clearInterval(this.timer)
        }
    
        // 组件渲染
        render() {
            return (
                
    ); } } /* ##################################################################################*/ //碰撞检测 函数 class PengZhuang extends Component { activate = true obj_polygonCollision_PASV = (obj, PASV) => { // 点 坐标转换 let point = { bottom: [obj.state.x + obj.state.w / 2, obj.state.y + obj.state.h], top: [obj.state.x + obj.state.w / 2, obj.state.y], left: [obj.state.x, obj.state.y + obj.state.h / 2], right: [obj.state.x + obj.state.w / 2, obj.state.y + obj.state.h / 2], } // 多边形 坐标转换 let obj_point = { a: [PASV.state.x, PASV.state.y], b: [PASV.state.x + PASV.state.w, PASV.state.y], c: [PASV.state.x + PASV.state.w, PASV.state.y + PASV.state.h], d: [PASV.state.x, PASV.state.y + PASV.state.h], } // 碰撞位置 回调函数 改变速度 if (this.activate) { // 上下 方向 进入 被动体 if (this.point_is_in(point.bottom, obj_point) || this.point_is_in(point.top, obj_point)) { DATA.bobble_v[1] *= -1 this.activate = false setTimeout(this.delay, 300) } // 左_右方向 进入 被动体 else if (this.point_is_in(point.left, obj_point) || this.point_is_in(point.right, obj_point)) { DATA.bobble_v[0] *= -1 this.activate = false setTimeout(this.delay, 300) } } } delay = () => { this.activate = true } //点 是否进入 被动体 point_is_in = (point, PASV) => { if (PASV.a[1] < point[1] && point[1] < PASV.c[1] && PASV.a[0] < point[0] && point[0] < PASV.c[0]) { return true } return false } render() { return (
    ); } } // 开始结束按钮 const StartStop = (e) => { const startStkle = { margin: '25px', // backgroundColor: "red" } return (
    {/* 按钮 */}
    ); } //控制按钮 class KongZhi extends Component { kongZhi = { margin: 'auto', backgroundColor: "red", width: '100px', height: '100px', position: 'absolute ', bottom: '0px', borderRadius: '50%', opacity: ' 0.5', display: 'block', textAlign: 'center', padding: '40px 0', } // 左 按钮 zuo_anXia = () => { DATA.block_v[0] = -DATA.control_v2 } // 右 按钮 you_anXia = () => { DATA.block_v[0] = DATA.control_v2 } // 弹起 按钮 tanQi = () => { DATA.block_v[0] = 0 } render() { return (
    ); } } // 板子 class BanZi extends Component { state = { x: 150, y: 680, h: 20, w: 100, } banZi = { width: `${this.state.w}px`, height: `${this.state.h}px`, position: 'absolute ', backgroundColor: 'blue', top: `${this.state.y}px`, } div_1 = createRef() move = (W) => { // 判断板子 是否碰到边缘 let maxW = W - parseFloat(this.banZi.width) if (this.state.x < 0) { this.setState({ x: 0 }) } else if (this.state.x > maxW) { this.setState({ x: maxW }) } // 刷新 状态 this.setState({ x: this.state.x + DATA.block_v[0] }) } render() { return (
    ); } } // 小球 class XiaoQiu extends Component { state = { x: 200, y: 400, h: 50, w: 50, } xiaoQiu = { width: `${this.state.w}px`, height: `${this.state.h}px`, position: 'absolute ', backgroundColor: 'red', borderRadius: '50%', } // 判断 是否碰到边缘 后移动 move = (H, W) => { let maxH = H - parseFloat(this.xiaoQiu.width) let maxW = W - parseFloat(this.xiaoQiu.height) // console.log("小球出了 左 边界") if (this.state.x < 0) { DATA.bobble_v[0] *= -1 this.setState({ x: 0 }) // console.log("小球出了 右 边界") } else if (this.state.x > maxW) { DATA.bobble_v[0] *= -1 this.setState({ x: maxW }) // console.log("小球出了 上 边界") } else if (this.state.y < 0) { DATA.bobble_v[1] *= -1 this.setState({ y: 0 }) // console.log("小球出了 下 边界") } else if (this.state.y > maxH) { DATA.bobble_v[1] *= -1 this.setState({ y: maxH }) // 移动 计算 } else { this.setState({ x: this.state.x + DATA.bobble_v[0], y: this.state.y + DATA.bobble_v[1], }) } } render() { return (
    ); } } // 方块 class Box extends Component { state = { x: this.props.attribute.x, y: this.props.attribute.y, w: this.props.attribute.w, h: this.props.attribute.h, c: this.props.attribute.c, } fangKuai = { margin: '2px', border: '2px solid green', position: 'absolute ', backgroundColor: 'green', } render() { return (
    ); } } // 方块 组 class BoxGroup extends Component { constructor(props) { // 必须在这里通过super调用父类的constructor super(props) this.state = { a: 0 } this.arr = [] this.activate = true this.init_arr() } // 初始化 数组 init_arr() { let sy = 0 let sw = 60 let sh = 20 let sc = 'green' for (var i = 0; i < 5; i++) { let sx = 0 for (var j = 0; j < 6; j++) { this.arr.push({ x: sx, y: sy, w: sw, h: sh, c: sc }) sx += 66 } sy += 23 } } //组 碰撞计算 boxGroup_Collision_PASV = (obj) => { for (let i in this.arr) { // 碰撞计算 this.Collision_PASV(this.arr[i], obj, i) } } // 单物体 碰撞计算 Collision_PASV = (box, obj, index) => { // 是否 允许计算 if (!this.activate) { return } // 如果 没有碰到 就是 碰到了 if (obj.x + obj.w < box.x || obj.x > box.x + box.w || obj.y + obj.h < box.y || obj.y > box.y + box.h) { } else { // 改变 数据中心的 小球速度 DATA.bobble_v[1] *= -1 // 改变 数组 // this.arr[index].c = 'red' console.log(index) // 停止 ??毫秒后 允许 this.activate = false setTimeout(() => this.activate = true, 10) } } render() { return (
    { this.arr.map( (item, index) => ( ) ) }
    ); } }

    临时文件

    import React, { Component, createRef } from 'react';
    
    
    
    
    // 主窗口
    export default class App extends Component {
        chuangKou = {
            width: '400px',
            height: '800px',
            margin: '15px',
            padding: '10px',
            position: 'absolute ',
            border: '2px solid #aaaaaa',
            top: '100px',
        }
        // boardRef = createRef() 
        controlRef = createRef()
        W = parseFloat(this.chuangKou.width)
        H = parseFloat(this.chuangKou.height)
        FPS = 60
    
        // 定义计数器 启动主时间序列
        yunXing = () => {
    
            // 板子 => 运行
            // this.boardRef.current.move(this.W, this.controlRef.current.state.speed)
    
        }
    
        // 开启计时器 
        timerStart = () => {
            console.log("时间序列 启动 FPS:25",)
            clearInterval(this.timer)
            this.timer = setInterval((this.yunXing), 1000 / this.FPS)
        }
        // 关闭计时器
        timerStop = () => {
            console.log("时间序列 关闭")
            clearInterval(this.timer)
        }
    
    
        // 组件渲染
        render() {
            return (
                
    ); } } // 开始结束按钮 const StartStop = (e) => { const startStkle = { margin: '25px', } return (
    {/* 按钮 */}
    ); } //控制按钮 class KongZhi extends Component { state = { speed: 0 } kongZhi = { margin: 'auto', backgroundColor: "red", width: '100px', height: '100px', position: 'absolute ', bottom: '0px', borderRadius: '50%', opacity: ' 0.5', display: 'block', textAlign: 'center', padding: '40px 0', } // 左 按钮 zuo_anXia = () => { this.setState({ speed: -2 }) } // 右 按钮 you_anXia = () => { this.setState({ speed: 2 }) } // 弹起 按钮 tanQi = () => { this.setState({ speed: 0 }) } render() { return (
    ); } } // 板子 class Board extends Component { state = { x: 0, y: 0, h: 20, w: 100, v: [0, 0], } board = { width: `${this.state.w}px`, height: `${this.state.h}px`, position: 'absolute', backgroundColor: 'blue', top: `${this.state.y}px`, } // 运行 更新 move = (W, speed) => { // // 判断板子 是否碰到边缘 // let maxW = W - this.state.w // if (this.state.x < 0) { // this.setState({ x: 0 }) // } // else if (this.state.x > maxW) { // this.setState({ x: maxW }) // } // //跟新 状态 // this.setState({ // x: this.state.x + this.state.v[0], // v: [speed[0], this.state.v[1]], // }) } render() { return (
    ); } }

    快捷键

    React快捷键(in VScode)

    1,imr :Import React
    
    2,imrc:Import React / Component
    
    3,imrs:Import React / useState
    
    4,imrse:Import React / useState useEffect
    
    5,cc:Class Component
    
    6,ccc:Class Component With Constructor
    
    7,sfc:Stateless Function Component
    
    8,cdm:componentDidMount
    
    9,uef:useEffect Hook
    
    10,cwm:componentWillMount
    
    11,scu:shouldComponentUpdate
    
    12,cwu:componentWillUpdate
    
    13,cdu:componentDidUpdate
    
    14,usf:Declare a new state variable using State Hook
    
    15,clg:console.log()
    
    16,rcredux:create redux
    
    17,rconst:create constructor
    
    18,rcc:react的类组件生成
    

    颜色吸取

    https://www.fontke.com/tool/pickrgb/

    底部

    你可能感兴趣的:(react,javascript,react.js,前端)