派大星

vuePress-theme-reco 派大星    2021 - 2022
派大星 派大星
主页
博客
  • 前端
  • JavaScript文章
  • 三级目录
  • 笔记
  • 学习笔记
  • 页面
  • CSS
  • HTML
  • 技术
  • 技术文档
  • GitHub技巧
  • 技术笔记
  • 实用工具
  • Nodejs
  • 博客搭建
  • 更多
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • JavaScript
  • 浏览器&网络
  • 前端框架
  • 资源工具
  • 持续集成
  • 小程序
  • 杂谈
  • React
  • Mysql
  • 面试题
  • uniapp
  • 《ES6 教程》笔记
  • 《Git》学习笔记
  • 《JavaScript教程》笔记
  • 《React》笔记
  • 核心概念
  • 高级指引
  • Hook
  • 案例演示
  • 《TypeScript 从零实现 axios》
  • 初识 TypeScript
  • TypeScript 常用语法
  • ts-axios 项目初始化
  • ts-axios 基础功能实现
  • ts-axios 异常情况处理
  • ts-axios 接口扩展
  • ts-axios 拦截器实现
  • ts-axios 配置化实现
  • ts-axios 取消功能实现
  • ts-axios 更多功能实现
  • ts-axios 单元测试
  • ts-axios 部署与发布
  • 《Vue》笔记
  • 基础
  • 组件
  • 过渡&动画
  • 工具
  • 规模化
  • 可复用性&组合
  • 其他
  • Vuex
标签
时间轴
关于
author-avatar

派大星

272

文章

69

标签

主页
博客
  • 前端
  • JavaScript文章
  • 三级目录
  • 笔记
  • 学习笔记
  • 页面
  • CSS
  • HTML
  • 技术
  • 技术文档
  • GitHub技巧
  • 技术笔记
  • 实用工具
  • Nodejs
  • 博客搭建
  • 更多
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • JavaScript
  • 浏览器&网络
  • 前端框架
  • 资源工具
  • 持续集成
  • 小程序
  • 杂谈
  • React
  • Mysql
  • 面试题
  • uniapp
  • 《ES6 教程》笔记
  • 《Git》学习笔记
  • 《JavaScript教程》笔记
  • 《React》笔记
  • 核心概念
  • 高级指引
  • Hook
  • 案例演示
  • 《TypeScript 从零实现 axios》
  • 初识 TypeScript
  • TypeScript 常用语法
  • ts-axios 项目初始化
  • ts-axios 基础功能实现
  • ts-axios 异常情况处理
  • ts-axios 接口扩展
  • ts-axios 拦截器实现
  • ts-axios 配置化实现
  • ts-axios 取消功能实现
  • ts-axios 更多功能实现
  • ts-axios 单元测试
  • ts-axios 部署与发布
  • 《Vue》笔记
  • 基础
  • 组件
  • 过渡&动画
  • 工具
  • 规模化
  • 可复用性&组合
  • 其他
  • Vuex
标签
时间轴
关于

React学习篇章二

vuePress-theme-reco 派大星    2021 - 2022

React学习篇章二

派大星 2021-01-01 React脚手架

# React02

# 回顾

React 用于构建用户界面的 JavaScript 库

国内三大框架

Vue [需要记忆一些写法,指令...]

React [在写大量的 JS 代码]

Augular [大型和重型的项目 大而全的框架] JS 框架

框架的热度,流不流行 github 的 start npmjs 包下载量

公司使用任何框架 在于公司目前技术栈的选择

React

编写方式:

  • 脚本引入方式 script src 属性

    react.js React 对象 管理 React 虚拟 DOM

    react-dom.js reactDOM 对象 渲染操作 DOM 的

    babel.js 转义 JS 语法 转义 JSX 语法为 JS 代码

JSX 语法 可以认为和 html 语法差不多,一些细节的属性,注意比如说 class className

{}JS 代码范围 里面的代码会被 JS 解析执行

组件封装方式:

  • rfc 函数组件 react function component 之前无状态组件

    之前函数组件无法使用 state 组件状态 hook

    16.8 版本已经可以

  • rcc 类组件 react class component 功能更为全面 之前 react 主流开发组件方式就是 rcc

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JSX语法</title>
</head>

<body>
    <div id="root"></div>
    <script src="/babel.min.js"></script>
    <script src="/react.development.js"></script>
    <script src="/react-dom.development.js"></script>
    <script type="text/babel">
        // 外部传入组件参数 状态 数据
    function Hero(props) {
        // es6 解构语法
        const{name,job,price} = props
        return (
        <div>
            <h1>名称:{name}</h1>
            <h1>职业:{job}</h1>
            <h1>价格:{price}</h1>
        </div>
        );
    }
    // 调用组件
    // 调用方式一  函数调用方式
    let vNode = Hero({
        name:'后裔',job:'射手',price:6800
    })
    // 调用方式二 组件标签方式调用
    // JS代码需要用{}包裹
    vNode =(<div>
        <Hero  name="凯"  job="打野" price="13888"/>
        <Hero  name="蔡文姬"  job="辅助" price="13888"/>
        <Hero  name="瑶"  job="辅助" price="13888"/>
        <hr/>
            {Hero({name:'后裔',job:'射手',price:6800})}
        </div>)
    ReactDOM.render(vNode, document.getElementById("root"));
    </script>
</body>

</html>

# 类组件

以类的方式封装组件 功能更为全面一些,早期(16.8 版本以前 )函数组件无法支持 state组件状态,组件生命周期,只能使用类组件

组件 hook 函数组件使用 state 和生命周期

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>类组件</title>
</head>

<body>
    <div id="root"></div>
    <script src="/babel.min.js"></script>
    <script src="/react.development.js"></script>
    <script src="/react-dom.development.js"></script>
    <script type="text/babel">
        // 类组件
        // es6语法中class是类的声明关键字
        // extends继承  可以得到 复用父类的功能
        // 继承React组件
        // 类名也是大驼峰
        class Hello extends React.Component{
            // 方法
            render(){
                return <h1>hello 类组件</h1>
            }
        }
        // 调用方式1:实例化对象使用
        // new 关键字 通过类实例化一个对象
        let vNode = new Hello().render();
        // 调用方式2:组件标签调用方式
        vNode = <Hello/>
        ReactDOM.render(vNode,document.getElementById("root"))
    </script>
</body>

类组件的传参

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>类组件传参</title>
</head>

<body>
    <div id="root"></div>
    <script src="/babel.min.js"></script>
    <script src="/react.development.js"></script>
    <script src="/react-dom.development.js"></script>
    <script type="text/babel">
        class HelloName extends React.Component{
            // react组件父类把props进行处理
            // 方法中使用可以通过this.props调用
            render(){
                return <h1>hello,{this.props.name}</h1>
            }
        }
        // JS语法调用
        let vNode = new HelloName({name:'类组件'}).render()
        // 组件标签方式调用
        vNode = <HelloName name="class component"/>
        // 复用
        vNode = (
            <div>
                {new HelloName({name:'类组件1'}).render()}
                {new HelloName({name:'类组件2'}).render()}
                {new HelloName({name:'类组件3'}).render()}
                <HelloName name="class1 component"/>
                <HelloName name="class2 component"/>
            </div>
        )
        ReactDOM.render(vNode,document.getElementById("root"))
    </script>
</body>

# 事件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JSX语法</title>
</head>

<body>
    <div id="root"></div>
    <script src="/babel.min.js"></script>
    <script src="/react.development.js"></script>
    <script src="/react-dom.development.js"></script>
    <script type="text/babel">
        class App extends React.Component{
            // 事件处理方法
            show(){
                alert('你点击到我了!')
            }
            // 返回一个标签
            showName(){
                return <h1>hello react</h1>
            }
            render(){
                return (
                    <div>
                        {/*调用显示标签 方法调用要立即执行   方法如果不需要立即调用就不需要写()*/}
                        {this.showName()}
                        {/*JSX语法里的主食*/}
                        {/*事件触发的方法不需要加(),加括号就立即触发了,这里点击事件触发后,再调用方法*/}
                        <button onClick={this.show}>点击显示</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<App/>,document.getElementById("root"))
    </script>
</body>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>事件触发后this的指向</title>
</head>

<body>
    <div id="root"></div>
    <script src="/babel.min.js"></script>
    <script src="/react.development.js"></script>
    <script src="/react-dom.development.js"></script>
    <script type="text/babel">
        class App extends React.Component{
            // 类属性 类变量
            name = "hello,react"
            show(){
                    // alert('show1触发了')
                    // this.属性名称 调用属性
                    /*
                    *事件触发后this指向谁?
                    *默认情况指向window
                    *严格模式下指向undefined
                    *React默认是严格模式
                    *this指向保持 怎么做?
                    *解决方案:绑定this操作
                    *bind  只绑定
                    *apply,call  绑定之后会调用方法
                    *this
                    * this就是组件对象
                    */
                    console.log(this);
                    console.log(this.name);
                    console.log();
                }
            render(){
                return (
                    <div>
                        {/*方法一:定义的是普通函数 bind绑定this*/}
                        <button onClick={this.show.bind(this)}>点击显示1</button>
                        {/*方法二:定义的是箭头函数 this指向不丢失*/}
                        <button onClick={this.show2}>点击显示2</button>
                        {/*方法三 事件触发的普通方法this丢失*/}
                        {/*事件触发箭头函数this指向正常*/}
                        <button onClick={()=>this.show()}>点击显示3</button>
                    </div>
                )
            }
            // 一个作用域快写的方法都是平级的
            // 箭头函数定义的方法 this的指向保持不丢失
            show2=()=>{
                console.log(this.name);
            }
        }
        ReactDOM.render(<App/>,document.getElementById("root"))
    </script>
</body>

# React 脚手架

node 环境

node -v

关于 node 版本 一般是根据公司的项目版本安装对应的版本

npm 命令

npm 仓库源地址

#检查地址
npm config get registry
#修改为国内镜像源
npm config set registry http://registry.npm.taobao.org/

# 生成项目包

npx 临时安装包软件的相关依赖命令 使用完毕之后删除

create-react-app react 脚手架

reactpro 项目包的名称 自定义

需要再哪儿生成项目 下载以下的命令即可

npx create-react-app reactpro

以上命令执行完毕之后

cd reactpro
npm start

访问流程:

  • 浏览器中输入localhost:3000 localhost 本地域名 3000 服务占用的端口
  • react 脚手架启动 3000 端口服务
  • react 启动的服务默认访问的就是 public 目录下
  • 在index.html中找到<div id="root"></div>挂在点
  • webpack 运行在自动打包index.js和index.html里
  • src/index.js 引入了 src

# 状态:

React

// rcc快捷方式
/**
 * Vue 组件的数据存放在data 数据自动监听的  当数据发生改变会自动刷新DOM 如果数据很多 会创建大量的监听器 性能就会低一些
 * React 需要的时候再去刷新DOM  没有自动监听器
 * React 提供了两个方法操作组件的状态
 * State 获取数据
 * setState 设置修改数据 刷新DOM
 * 微信小程序借鉴了React数据管理
 */
import React, { Component } from "react";

export default class App extends Component {
  // state初始化
  state = { num: 1 };
  // +1方法
  doAdd() {
    // 修改state的数据
    // sst快捷提示
    this.setState({ num: this.state.num + 1 });
  }
  render() {
    return (
      <div>
        <h1>{this.state.num}</h1>
        <button onClick={this.doAdd.bind(this)}>点击这里</button>
      </div>
    );
  }
}

# setState

import React, { Component } from "react";

export default class App extends Component {
  // 普通成员属性
  num = 1;
  // 事件处理方法 num+1
  doAdd = () => {
    this.num++;
    console.log(this.num);
    // 使用setState刷新DOM值必须写入{}
    this.setState({});
  };
  render() {
    return (
      <div>
        <h1>{this.num}</h1>
        <button onClick={this.doAdd}>点击加1</button>
      </div>
    );
  }
}

# setState 具有异步性

import React, { Component } from "react";

export default class App extends Component {
  // 存储成state属性还是使用普通类成员
  // 如果状态不需要渲染到DOM上,使用普通类成员属性
  // 如果状态频繁发生改变需要修改渲染DOM 使用state
  doChange() {
    // sst快捷方式
    // setState参数结构(参数1,参数2)
    // 参数1:需要修改的state的数据 对象格式
    // 参数2:回调方法 当DOM渲染完毕之后调用
    // setState 修改state属性操作 是异步的 非阻塞  提高性能
    // 如果业务操作中 有需求是需要修改state状态后操作的 这个操作就是需要卸载回调方法中
    this.setState({ num: 100 }, () => {
      console.log("页面渲染完毕num:", this.state.num);
    });
    // 修改后打印state值
    console.log("num:", this.state.num);
  }
  state = { num: 1 };
  render() {
    return (
      <div>
        {/**这里的方法调用加() */}
        {/**事件触发的方法 当事件触发时 在调用不加() */}
        {/* <button onClick={this.doChange}>点击这里</button> */}
        {/* 箭头函数触发 事件触发箭头函数  箭头函数要立即调用普通函数方法 */}
        <button onClick={() => this.doChange()}>点击这里</button>
      </div>
    );
  }
}

# 样式使用

标签属性 style 行内样式

属性 class

/**
 * style 行内样式
 */
import React, { Component } from "react";
import "./assets/App.css";
export default class App extends Component {
  size = 18;
  // 练习:写一个按钮点击之后字体变大
  // 分析:1.编写一个按钮并绑定点击事件
  // 2.事件处理方法里 对size属性+1
  // 3.刷新DOM
  doChange() {
    this.size++;
    // 刷新DOM渲染页面
    this.setState({});
  }
  render() {
    return (
      <div>
        {/* JS描述样式的方式 */}
        <div style={{ color: "red", fontSize: this.size }}>Hello React</div>
        <button onClick={this.doChange.bind(this)}>点击放大字体</button>
        <div className="danger">WEB2108</div>
        {/* 动态改变绑定的样式class 根据size变量 */}
        {/* <22 success  否则就是danger */}
        <div className={this.size < 22 ? "success" : "danger"}>WEB2108</div>
        {/* <22 sucess; 22-25 warn;>25 danger */}
        {/* 如果再属性中写JS代码比较多的时,建议封装为方法 */}
        {/* 只有事件触发的方法 调用不加() */}
        <div className={this.showClass()}>WEB2108</div>
      </div>
    );
  }
  showClass() {
    // <22 success;22-25 warn; >25danger>
    if (this.size < 22) return "success";
    if (this.size > 25) return "danger";
    return "warn";
  }
}

# 图片加载

import React, { Component } from 'react'
import mypng  from './assets/1.jpg'
export default class App extends Component {
  render() {
    return (
      <div>
        {/* 远程地址 直接填写图片地址即可 */}
        <img src="https://www.google.com.hk/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png" alt="" />
        {/* 本地图片 习惯放在/src/assets目录下 */}
        {/* 方法一 使用require语法 .default后缀 现在版本可以不用写 */}
        <img src={require("./assets/1.jpg")} alt="" />
        {/* 方法二  import mypng时引入的别名变量名称 */}
        <img src={mypng} alt="" />
      </div>
    )
  }
}

# 条件渲染

import React, { Component } from 'react'
import './assets/App.css'
export default class App extends Component {
  score = 60
  // delta 时表示变量的意思
  changeScore(delta){
    // 修改分数
    // this.score = this.score+delta;
    this.score +=delta
    // 刷新DOM
    this.setState({})
  }
  render() {
    return (
      <div>
        <h4>当前分数为:{this.score}</h4>
        <button onClick={this.changeScore.bind(this,-10)} disabled={this.score<=0}>-10分</button>
        <button onClick={this.changeScore.bind(this,10)} disabled={this.score>=100}>+10分</button>
        {/* 如果分数大于等于60  则显示及格了  否则显示不及格 */}
        {this.show()}

      </div>
    )
  }
  show(){
    if(this.score >=60){
      // 返回JSX语法 不要加引号  加了引号返回的就是字符串了
      return <div className='success'>及格</div>
    }
    else{
      return <div className='danger'>不及格</div>
    }
  }
}

# 双向绑定

在表单元素中

单项流数据:数据渲染到页面 DOM 上

双向流数据:既满足单向流数据,又可以接收到用户输入的信息

数据和页面时双向的

数据<=>页面

vue 双向绑定v-model本质就是 v-bind v-on 结合的语法糖

import React, { Component } from 'react'

export default class App extends Component {
  state = {name:'皮卡丘'}
  _nameChange(e){
    // e.target.value 文本框输入的值
    console.log(e.target.value);
    let name = e.target.value
    this.setState({name})
  }
  render() {
    // es6结构语法 后续调用为了更加方便一些
    const {name} = this.state
    return (
      <div>
        <input type="text" value={name} onChange={this._nameChange.bind(this)}/>
      </div>
    )
  }
}