React01-yarn包管理器

React01-yarn包管理器

安装Nodejsd的默认会给你们安装包管理器npm

介绍yarn包管理器,这个包管理器和npm一样,都是可以去下载对应依赖

npm包管理器缺陷:

npm的下载比较慢,镜像默认是国外的镜像,我们国内可以配置淘宝镜像。 同一项目我们不同时间下载依赖,可能遇到包版本不一致的情况。经常下载依赖过后,版本~5.0.3表示你们安装的版本5.0.x版本。这个x值是一个可变的值。 下载报错问题,npm进行包管理下载的时候,同一时间下载多个包,其中某一个包出现下载报错。其他包会正常继续下载。某个包出现问题,项目跑不起来。

yarn包管理器特点:

在react中经常会使用的一个包管理器,官网也推荐我们用yarn包管理器

快速性:下载依赖也可以配置国内镜像,下载过的每个包都可以被缓存起来,下次就不用再重新下载,直接从缓存里面获取 安全性:在执行代码之前,yarn包管理器会根据一些算法验证这个包是否安全,完整性验证 并行安装:如果同时下载很多任务,并安装到本地,我们并行执行 安装版本统一:yarn来下载我们包,版本号是固定的。在我们项目中yarn.lock这个文件中就会将版本锁定 命令比较简单:相对于npm来说,yarn的命令比较由语义

一、下载yarn

目前每个同学的电脑环境都不一样,有的win7、win10、win11.保证每个同学的电脑都能正常使用yarn

yarn的官方文档:https://yarn.bootcss.com

 npm install yarn -g

检测版本

 yarn --version

使用命令查看yarn的配置

 yarn config list

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

node-sass下载到本地很慢,甚至可能下载失败

二、使用命令

初始化项目  yarn init --y 你们项目中就会出现一个package.json文件。这个文件里面存放依赖信息 添加依赖  yarn add 包名

 yarn add 包名@版本号 比如:  yarn add jquery

 yarn add vue@2.6.10 添加开发依赖  yarn add webpack --dev --dev代表这个包开发依赖,开发环境下可以使用,打包后生成环境不需要将这个依赖打包过去 dependencies存放的包都是生成环境需要依赖。 devDependencies: 开发依赖,这个包只在你们开发过程中有用,项目打包后就不需要这个依赖。不打包最后生产环境中 删除依赖 yarn remove jquery

yarn remove jquery@版本

npm 命令yarn 命令npm installyarn add/yarn installnpm install [package] —saveyarn add [package]npm install [package] —save-devyarn add [package] —devnpm install package(https://github.com/1).1.1 —saveyarn add package(https://github.com/1).1.1npm uninstall [package] —save(-dev)yarn remove [package]npm update —saveyarn upgradenpm inityarn init

React02-React介绍和安装

React02-React介绍和安装

一、React基本概念

学习一个新的框架,一个新的技术

React官网:https://reactjs.org

React中文网站:https://react.docschina.org

React项目起源于facebook内部,2013年5月开源的一个前端框架。起初是facebook是为了公司内部研发一个产品,但是发现市面上所有的框架都不好用,他们自己研发React框架

React有两条路线:React本身用于开发PC端页面

React-Native:使用React来开发移动端,主要android、ios

优势:

技术成熟、社区完善、配件齐全。适合于中大型项目设计 由facebook专门团队来维护和更新产品。产品稳定性和质量可靠 开发非常灵活,在项目中可发挥的余地比较大

Vue和React这两个框架:

Vue是高度封装的一个前端框架,自动档

React是一个基于JS逻辑来开发业务的一个前端框架、手动挡

在React中没有路由守卫,我们自己写一个路由。

官方将React称为一个JS库?

官方只跟我们提供的React基础内容。没有路由、状态机

React框架(React全家桶=React官方基础+第三方路由+第三方状态机)

二、搭建项目

目前React最新的版本是18

我们一般常见项目

npx create-react-app 项目名字

这是目前官方推荐的安装项目方式

不用在本地安装脚手架,临时在本地搭建一个脚手架,项目创建完毕后删除脚手架

可以保证创建项目脚手架是最新

创建项目的时候,你们项目名字不要由大写字母,全小写。如果遇到多个单词你们可以用-或者_

my-projectmy_project

创建项目成功后

Success! Created my-project at C:\Users\xuchaobo\Desktop\21期班级\第五阶段\Code\my-project

Inside that directory, you can run several commands:

npm start

Starts the development server.

npm run build

Bundles the app into static files for production.

npm test

Starts the test runner.

npm run eject

Removes this tool and copies build dependencies, configuration files

and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

cd my-project

npm start

Happy hacking!

提示你要执行两个命令

cd my-project

然后启动项目

npm start

yarn start

目前React脚手架要求最低的node版本是14以上的。

React03-JSX概念

React03-JSX概念

一、什么是JSX

JSX=JavaScript+XML

JSX可以说是JS的一种扩展语法,他就是将JavaScript和XML代码进行结合(XML也是一种标签语法)

HTML:超文本标记语言,重在显示

XML:可扩展的标记语言,重在传输

两则都是ML标记语言,你们在JSX中写代码不是HTML代码,实际上XML。但是都是标记语言,理解写的HTML代码也可以

JSX就是一种JS封装,好处就是JS中直接嵌入HTML模板代码。最后交给我们脚手架工具,脚手架工具默认将JSX代码编译为JS代码,拿到浏览器运行

JSX特点:

JSX执行更快,因为他在编译的时候就可以进行优化 JSX类型安全的,编译过程中如果遇到问题,抛出错误。编译过程 JSX写起来会比我们纯JS更加简单

二、插件安装

React组件有两种开发方式

用类来开发组件:要用面向对象 快捷键:RCC

用函数来开发组件:只需要会定义函数就可以 快捷键:RFC

目前暂时推荐大家用函数组件

三、基础表达式

import React from 'react'

export default function JSXDemo() {

// 定义数据

const username = "xiaowang"

const number1 = 20

const number2 = 30

const age = 18

const user = {

username:"bobo"

}

// 定义一个函数

const show = (val)=>{

return val.toUpperCase()

}

const array = [1,3,5,8]

const array2 = [

{id:1,name:"xiaowang"},

{id:2,name:"xiaofeifei"},

]

const array3 = [

  • 1
  • ,

  • 2
  • ,

  • 3
  • ]

    const array4 = array2.map(item=>{

    return

  • {item.id}--{item.name}
  • })

    // [

  • xiaowang
  • ,
  • xiaofeifei
  • ]

    return (

    JSX学习

    {/* 基础的语法 */}

    {username}

    {number1 + number2}

    {/* 条件运算 */}

    {age>=18?"成年":"未成年"}

    {/* 对象表达式,不能直接输出对象 */}

    {user.username}

    {/* 函数表达式,类似于Vue过滤器 */}

    {show("abcd")}

    {/* 数组表达式 */}

    {/* React的模板,默认将数组里面输出进行遍历 */}

    {array}

    {/*

    {array2}

    */}

      {array3}

      {array4}

    )

    }

    四、JSX中的样式

    JSX 支持两种样式

    行内样式:直接在模板上面添加style属性,里面写css样式代码。 JSX将所有的css代码都做了封装,必须要使用JSX封装好的css代码 import React from 'react'

    export default function JSXStyle() {

    return (

    JSXStyle

    蜗牛学院

    )

    }

    目前JSX代码中行内样式都被封装,以前font-size变成fontSize了 外部样式 行内样式我们不好维护,我们可以将css样式提取到外部去 引入到组件中使用 你可以项目assets目录下面创建style文件夹,以后所有的css样式都在放这个文件夹里面 home.css 文件 .active{

    color:green

    }

    .as{

    width: 100px;

    height: 100px;

    background-color: red;

    }

    在组件中引入外部样式 import React from 'react'

    import "../assets/styles/home.css"

    export default function JSXStyle() {

    return (

    JSXStyle

    蜗牛学院

    {/* 要给div增加class属性,不能写class,必须要className */}

    {/* 注释的快捷键:ctrl+/ */}

    测试

    )

    }

    React04-组件开发

    React04-组件开发

    React中组件也是将UI部分进行拆分。

    React组件功能层面会分类两类:

    UI组件:专注于视图的显示渲染 容器组件:专注于业务的实现

    在开发过程中我们并没有强调UI组件何容器组件之间划分。一般在一个组件中既有UI部分渲染,也有业务逻辑数据定义。

    一、组件分类

    React从组件类型(技术层面)会分类两类

    类组件:采用面向对象的语法来开发 函数组件:采用函数式编程来进行开发

    在学习过程中需要区分

    一个项目既有类组件,又有函数组件,这两类组件我们都必须掌握。

    区别:

    类组件开发需要面向对象基础知识点。ES6面向对象基础语法。有状态(响应式数据)组件 函数组件开发采用函数式编程,相对来说简单一些。无状态的组件。学习hooks编程

    二、创建类组件

    创建类组件,我们需要在页面上RCC来动态生成模板

    import React, { Component } from 'react'

    export default class Header extends Component {

    render() {

    return (

    Header

    )

    }

    }

    特点:

    子类必须要继承一个Component,才能称为组件 需要在组件中重写render方法,这个方法就是页面渲染的节点代码 需要将当前这个组件暴露出去

    三、创建函数组件

    import React from 'react'

    export default function Content() {

    return (

    Content

    )

    }

    函数组件相对来说要简单一些。只需要暴露一个函数,里面returnJSX代码就可以了

    但是函数组件也有缺陷:函数组件是无状态的组件,内部的数据无法响应式变化

    四、组件中使用图片

    网络图片跟以前一样,直接引入地址就可使用

    本地图片不能直接引入,因为我们在本地存放assets目录,打包后不存在。

    打包后图片、css、js代码会默认放在static目录下面。

    页面中本地图片找不到图片路径

    语法一:

    import React, { Component } from 'react'

    import wechat from "../../assets/images/wechat.jpg"

    export default class Picture extends Component {

    render() {

    return (

    Picture

    react.js typescript vue.js 一站式React+TS+Vue3+Umi基础知识汇总  第1张

    )

    }

    }

    第一种方式就是将图片采用模块化的方式引入进来。打包的时候,默认找你们打包后的图片路径。

    import React, { Component } from 'react'

    import wechat from "../../assets/images/wechat.jpg"

    // 后端模块化

    const img = require("../../assets/images/wechat.jpg")

    export default class Picture extends Component {

    render() {

    return (

    Picture

    react.js typescript vue.js 一站式React+TS+Vue3+Umi基础知识汇总  第2张

    react.js typescript vue.js 一站式React+TS+Vue3+Umi基础知识汇总  第1张

    react.js typescript vue.js 一站式React+TS+Vue3+Umi基础知识汇总  第4张

    react.js typescript vue.js 一站式React+TS+Vue3+Umi基础知识汇总  第5张

    )

    }

    }

    通过require可以在图片加载的时候,引入这个图片资源。

    本地图片用的少,一般都是网络图片

    css代码中需要使用本地图片

    外部的css直接引入本地图片就可以加载成功

    标签上面的样式,我们使用style需要动态引入

    总结:只要JSX标签里面要使用本地图片,考虑动态引入图片。

    五、组件中样式

    JSX中允许两种样式

    内部样式:style标签 外部样式:引入的时候,组件之间会相互影响

    样式穿透:在React中样式穿透全局影响。

    样式模块化

    我们需要将样式设置为模块化,你在哪个组件中引入这个样式,只能在这个组件作用

    没有模块化,css外部样式就是全局的样式

    (1)在设计样式文件名字,必须满足下面规则

    index.css——>index.module.css

    (2)在组件中引入的时候,必须模块化引入

    // import "../../assets/styles/index.module.css"

    import IndexStyle from "../../assets/styles/index.module.css"

    (3)在使用的时候,必须指定从哪个模块获取css样式

    export default function StyleDemo01() {

    return (

    StyleDemo01

    )

    }

    完整的代码

    import React from 'react'

    // module,这个css必须模块化引入静态引入

    // import "../../assets/styles/index.module.css"

    import IndexStyle from "../../assets/styles/index.module.css"

    export default function StyleDemo01() {

    return (

    StyleDemo01

    woniu

    xueyuan

    孵化园

    )

    }

    六、组件中的事件

    React要使用事件,不是在原生事件,React中所有事件都已经被封装。

    JSX提供的CSS封装过后的css 。font-size—->fontSize

    JSX提供的事件也是封装过后的事件。onclick—->onClick

    onclick属于原生DOM事件,浏览器都能识别。

    onClick属于合成事件(JSX封装过后事件)。是React已经处理过的事件

    (1)事件类型

    在dom中直接绑定事件

    odiv.onclick = function(){}

    osel.onchange = function(){}

    radio.onchange

    input.onblur = function(){}

    dom事件是直接绑定到dom身上,主要dom原生触发这个动作,执行你们事件函数

    不是onclick才有事件,事件一直都有,onclick监听这个动作

    在React中事件称为合成事件,不是直接绑定在dom身上。以后再JSX中给一个原生绑定onClick,默认不是再dom原生身上绑定这个事件。(合成事件原理?)

    onclick ===> onClick

    onchange ===> onChange

    onblur ===> onBlur

    事件名字发生变化,采用驼峰命名的方式

    基础代码

    import React, { Component } from 'react'

    export default class EventComp extends Component {

    play() {

    console.log(123);

    }

    show(){

    console.log(234);

    }

    render() {

    return (

    EventComp

    )

    }

    }

    (2) this指向的问题

    import React, { Component } from 'react'

    export default class EventComp extends Component {

    play() {

    console.log("正在玩耍");

    }

    show(){

    // React不能直接让你获取当前节点,默认给你undefined

    console.log(this);

    this.play()

    }

    render() {

    return (

    EventComp

    )

    }

    }

    如果你组件中定义的事件函数是普通函数,默认获取到this值为undefined。React默认不允许直接获取节点

    绑定事件是普通函数,改变this指向当前组件

    bind默认返回一个函数。onClick={函数}

    箭头函数下面就不存在this执行错误的情况

    import React, { Component } from 'react'

    export default class EventComp extends Component {

    message = ()=>{

    console.log(this);

    }

    render() {

    return (

    EventComp

    )

    }

    }

    推荐大家以后再定义事件函数的时候,必须用箭头函数来实现。你也可以不用箭头函数,必须搞清楚this指向

    面试题:你说一下React中事件的特点?

    React中的事件并不是直接绑定DOM原生身上,合成事件(?)

    React中事件绑定,如果普通函数,this默认执行undefined,如果是箭头函数this默认执行当前组件

    (3)阻止事件默认行为

    (阻止冒泡)e.stopPropagation()

    deleteTopNav = (e) =>{

    e.stopPropagation()

    }

    {this.deleteTopNav(e)}}>X

    (4)事件委托

    changeStatus = (event) => {

    const id = event.target.getAttribute("index")

    };

      {filterArr.map((item) => {

      return (

      key={item.id}

      index={item.id}

      className={item.status ? Styles.done : ""}

      >

      {item.task}

      );

      })}

    React05-组件内部state

    React05-组件内部state

    一、回顾Vue

    回顾:组件的数据由两部分组成

    内部数据,比如data里面定义的数据组件自己内部数据 外部数据,props来接受到的数据都是外部数据

    不管是内部数据还是外部数据,只要发生变化页面都会响应式变化。

    React的数据由两部分组成

    内部数据,组件内部自己定义的数据,必须按照要求来定义,才能称为内部数据 内部外部数据,父组件传递过来的数据

    二、内部状态

    内部的state数据

    React内部数据的定义我们必须使用一个变量state来表示

    (1)定义数据

    export default class ListComp extends Component {

    constructor() {

    super()

    this.state = {

    list:[

    { id: 1, name: "xiaoawng", age: 17 },

    { id: 2, name: "xiaofei", age: 18 },

    { id: 3, name: "xiaozhang", age: 20 },

    ]

    }

    }

    我们可以在构造函数里面自己写一个state属性(必须是这个属性),在里面定义好你的数据

    import React, { Component } from 'react'

    export default class ListComp extends Component {

    state = {

    list: [

    { id: 1, name: "xiaoawng", age: 17 },

    { id: 2, name: "xiaofei", age: 18 },

    { id: 3, name: "xiaozhang", age: 20 },

    ]

    }

    这个state就相当于Vue中data。里面数据能够实现响应式变化

    (2)数据的获取

    {

    this.state.list.map(item => {

    return (

    {item.id}

    {item.name}

    {item.age}

    )

    })

    }

    一般不建议你们直接在模板代码中this.state.list来获取数据

    render() {

    const {list} = this.state

    return (

    ListComp

    {

    list.map(item => {

    return (

    )

    })

    }

    编号名字年龄操作
    {item.id}{item.name}{item.age}

    )

    }

    建议我们在开发过程中,先render方法里面讲需要的数据结构赋值出来。

    以后页面中可以重复使用,不要频繁操作this.state

    (3)修改数据

    在react组件中我们要修改数据,必须使用setState这个函数来执行

    直接修改state的数据,页面并不能更新,render不会被触发,

    你调用setState,一旦这个方法执行完毕后,默认底层调用render,页面就能实现动态渲染

    this.setState({

    list:新的list

    })

    实际代码

    deleteRow = (id) => {

    this.setState({

    list: this.state.list.filter(item => item.id != id),

    username:"xiaofeifei"

    })

    }

    练习:

    定义一个数组,数组里存放user对象

    在页面动态渲染出对象。

    点击删除后删除指定的对象

    三、state的特点

    异步更新

    我们在调用setState这个函数的时候,默认是异步更新。

    Vue的更新过程也是异步的过程。

    更新过程需要消耗比较多的时候,同步代码。页面在加载等待这个结果

    changeUsername = ()=>{

    this.setState({

    username:"夏青松"

    })

    console.log(this.state.username);

    }

    如果更新后我们需要拿到更新的结果,可以传递第二个参数

    changeUsername = ()=>{

    this.setState({

    username:"夏青松"

    },()=>{

    console.log(this.state.username);

    })

    }

    异步更新,更新完毕后默认调用回调函数。

    合并我们操作

    当我们在一个函数中执行多次setState数据更新。默认将多次操作合并在意思

    changeUsername = ()=>{

    // this.setState({

    // username:"夏青松"

    // },()=>{

    // console.log(this.state.username);

    // })

    this.setState({

    username:"夏青松"

    })

    this.setState({

    username:"夏青松"

    })

    }

    render方法最后只会执行一次。底层对你们的setState操作进行合并。最终渲染一次

    底层:当我们检测到同一个任务中执行多个seState,底层提供一个队列。将你们修改数据的操作默认放在队列里面排队。所以底层更新他是异步的。

    在放入队列之前,判断你们的操作是否有重复,是否需要合并,有重复操作踢出重复过程,如果有多个修改任务,将修改采用Object.assign方法合并在一起,在加入队列中等待异步修改。

    底层做的性能优化

    强制更新

    React其实也提供了一个强制更新的api

    changeUsername = ()=>{

    // this.setState({

    // username:"夏青松"

    // },()=>{

    // console.log(this.state.username);

    // })

    // this.setState({

    // username:"夏青松"

    // })

    // this.setState({

    // username:"夏青松"

    // })

    // this.setState({

    // password:"333"

    // })

    this.state.username = "徐豪"

    // 强制更新,强行让底层调用render方法

    // Vue中也有这个函数,this.$fouceUpdate()

    this.forceUpdate()

    }

    当你们页面发生数据变化,没有调用setState的时候,我们可以强制让React调用render方法

    尽量少用。

    React06-组件通信

    React06-组件通信

    一、父子组件通信

    在React中我们也需要完成父子组件通信。

    一个组件的数据来源两部分:

    组件内部state 组件外部的props

    二、父传子

    在父组件定义state内部数据,将这个数据动态传递给子组件

    import React, { Component } from 'react'

    import ChildrenComp from './ChildrenComp'

    export default class ParentComp extends Component {

    state = {

    username:"xiaowang"

    }

    changeUsername = ()=>{

    this.setState({

    username:"xiaozhang"

    })

    }

    render() {

    const {username} = this.state

    return (

    ParentComp

    {username}

    10">

    )

    }

    }

    在子组件上面你们可以传递动态属性,也可以传递静态的属性值。

    父组件更新了state数据,传递给子组件自动更新

    参数传递的一些技巧