b站React禹哥版视频笔记-React应用(基于react脚手架)

前言

上一篇:React面向组件编程(下)
本篇内容:React应用(基于react脚手架)

一、初始化react脚手架

1.react脚手架:

1.xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目

a.包含了所有需要的配置(语法检查、jsx编译、devServer…)
b.下载好了所有相关的依赖
c.可以直接运行一个简单效果

2.react提供了一个用于创建react项目的脚手架库: create-react-app
3.项目的整体技术架构为: react + webpack + es6 + eslint
4.使用脚手架开发的项目的特点: 模块化, 组件化, 工程化

2.创建项目并启动

  1. 全局安装:npm i -g create-react-app
  2. 切换到你想创建项目的目录下,使用命令:create-react-app xxx(项目名,比如,hello-react)
  3. 进入项目文件夹:cd hello-react
  4. 启动项目:yarn start或npm start
    注:若create-react-app安装失败,可以尝试更换npm源,更换成淘宝的,参考
    在这里插入图片描述
    在这里插入图片描述
    安装成功后:在这里插入图片描述
    启动项目:在这里插入图片描述
    会让你选择用哪个浏览器打开,成功的页面(即成功运行了react官方给的模板项目):

二、脚手架文件介绍

1.public

public文件一般存静态资源,比如页面、样式、公共的图片

以后写项目时,只有一个.html文件,也就是单页面应用(SPA)

favicon.icon ------ 网站页签图标
index.html -------- 主页面
logo192.png ------- logo图
logo512.png ------- logo图
manifest.json ----- 应用加壳的配置文件
robots.txt -------- 爬虫协议文件

2.src

App.js:定义了一个组件App
App.css:组件App的样式文件
App.test.js:测试App的,我们几乎不用
index.css:通用的样式
index.js:入口文件
logo.svg:logo图片
reportWebVitals.js:记录页面性能,里面用了web-vitals库
aetupTest.js:用于组件测试,里面用了第三方库web-vitals

三、一个简单的Hello组件

后缀同为.js,区分组件文件和普通js文件:
1.组件文件首字母大写,普通js文件首字母小写
2.把组件文件后缀改为.jsx

上图中的写法在App.js中引入组件时略显臃肿,下图中是另一种写法:

四、样式的模块化

当两个组件样式中有相同的className时,后引入的组件样式会覆盖掉之前的样式

  1. 把文件名改为index.module.css
  2. 引入css文件时:import hello from './index.module.css'
  3. 使用样式时:className={hello.title}

样式的模块化用的不是很多,一般用less的嵌套写法即可

五、vscode中react插件的安装

在vscode的插件市场中搜索react👇
在这里插入图片描述
比如,一些代码片段:
rcc:类式组件
rfc:函数式组件

六、组件化编码流程

tips:
①打开终端快捷键:ctrl + ~
②停止运行快捷键:ctrl + C

  1. 拆分组件: 拆分界面,抽取组件

  2. 实现静态组件: 使用组件实现静态页面效果

  3. 实现动态组件
    3.1 动态显示初始化数据

    3.1.1 数据类型
    3.1.2 数据名称
    3.1.2 保存在哪个组件?
    

    3.2 交互(从绑定事件监听开始)

七、组件的组合使用-TodoList案例

功能: 组件化实现此功能

  1. 显示所有todo列表
  2. 输入文本, 点击按钮显示到列表的首位, 并清除输入的文本

1.静态组件

  1. App.js中引入模块的顺序
    ①外部模块②自己的模块③样式文件
  2. 拆分List与Item时,先把List整个拆分,再在List里面拆分Item

2.动态初始化列表

数据存放在App的state中,传给子组件List:

export default class App extends Component{
    // 初始化状态
    state={todos:[
        {id:'001',name:'吃饭',done:true},
        {id:'002',name:'睡觉',done:true},
        {id:'003',name:'敲代码',done:false},
    ]} 

    render(){
        const {todos}=this.state;
        return (
                <div className="todo-container">
                    <div className="todo-wrap">
                    <Header/>
                    <List todos={todos}/>
                    <Footer/>
                    </div>
                </div>
        )
    }
}

把List中的数据批量传递给其子组件Item:

export default class List extends Component{
    render(){
        const {todos}=this.props;
        return (
            <ul className="todo-main">
                {
                    todos.map(todo=>{
                        // return <Item key={todo.id} id={todo.id} name={todo.name} done={todo.done}/>
                        return <Item key={todo.id} {...todo}/>  // 批量传递
                    })
                }
            </ul>
        )
    }
}

Item组件接收数据:

export default class Item extends Component {
  render() {
    const {name,done}=this.props
    return (
          <li>
            <label>
                <input type="checkbox" defaultChecked={done}/>
                <span>{name}</span>
            </label>
            <button className="btn btn-danger" style={{display:'none'}}>删除</button>
          </li>
    )
  }
}

3.添加todo

父给子传数据:props
子给父传数据:利用函数

比如子组件Header给父组件App传数据:

需要给input框绑定一个键盘事件:onKeyUp

专门生成唯一id的库:uuid
安装:yarn add uuid或者npm i uuid
但这个库有点大,不推荐,推荐nanoid

import React, { Component } from 'react'
import {nanoid} from 'nanoid'

import './index.css'

export default class Header extends Component {
  handleKeyUp=(event)=>{
    // 解构赋值获取keyCode,target
    const {keyCode,target}=event
    // 判断按下的是否为回车键
    if(keyCode!==13) return
    //添加的todo名字不能为空
    if(target.value.trim()===''){
      alert('输入不能为空!')
      return
    }
    // 准备好一个todo对象
    const todoObj={id:nanoid(),name:target.value,done:false}
    // 将todoObj传递给App
    this.props.addTodo(todoObj)
    // 清空输入
    target.value=''
  }
  render() {
    return (
      <div className="todo-header">
            <input onKeyUp={this.handleKeyUp} type="text" placeholder="请输入你的任务名称,按回车键确认"/>
      </div>
    )
  }
}

4.鼠标移入效果

鼠标悬浮在某一项上面时,该项高亮,且后面出现“删除”按钮

export default class Item extends Component {
  state={mouse:false}

  handleMouse=(flag)=>{
    return ()=>{
      console.log(flag)
      this.setState({mouse:flag})
    }
  }

  render() {
    const {name,done}=this.props
    const {mouse} = this.state
    return (
          <li style={{backgroundColor:mouse?'#ddd':'white'}} onMouseEnter={this.handleMouse(true)} onMouseLeave={this.handleMouse(false)}>
            <label>
                <input type="checkbox" defaultChecked={done}/>
                <span>{name}</span>
            </label>
            <button className="btn btn-danger" style={{display:mouse?'block':'none'}}>删除</button>
          </li>
    )
  }
}

3.添加一个todo

根据勾选或者未勾选,更改状态里的值

tips:状态在哪里,操作状态的方法就在哪里
App给List传递props:

<List todos={todos} updateTodo={this.updateTodo}/>
// updateTodo用于更新一个todo对象
    updateTodo=(id,done)=>{
        // 获取状态中的todos
        const {todos}=this.state
        // 匹配 处理数据
        const newTodos=todos.map((todoObj)=>{
            if(todoObj.id===id) return {...todoObj,done}
            else return todoObj
        })
        this.setState({todos:newTodos})
    };

List给Item传递props:

return <Item key={todo.id} {...todo} updateTodo={updateTodo}/>

Item中的回调函数;

 // 勾选、取消勾选某一个todo的回调
  handleCheck=(id)=>{
    return (event)=>{
      // console.log(id,event.target.checked)
      this.props.updateTodo(id,event.target.checked)
    }
  }

4.对props进行限制

安装第三方库:yarn add prop-types
引入:import PropTypes from 'prop-types'
对传递的props进行类型以及必要性的限制:
Header组件中:

static propTypes={
    addTodo:PropTypes.func.isRequired
  }

List组件中:

static propTypes={
        todos:PropTypes.array.isRequired,
        updateTodo:PropTypes.func.isRequired
    }

5.删除一个todo

App组件中:

// deleteTodo用于删除一个todo对象
    // tips:不能用delete,因为delete是个关键字,用于删除对象中的某个属性
    deleteTodo=(id)=>{
        // 获取原来的todos
        const {todos}=this.state
        // 删除指定id的todo对象
        const newTodos=todos.filter((todoObj)=>{
            return todoObj.id!==id
        })
        // 更新状态
        this.setState({todos:newTodos})
    }

Item组件中:

// 删除一个todo的回调
  handleDelete=(id)=>{
    // console.log('通知App删除',id)
    // alert键只有确认
    if(window.confirm('确定删除吗?')){
      this.props.deleteTodo(id)
    }
  }

6.实现底部功能–Footer

tips:defaultChecked只在第一次时起作用
App组件给子组件Footer传递函数:

<Footer todos={todos} checkAllTodo={this.checkAllTodo} checkAllDone={this.checkAllDone}/>

在App组件中修改状态的值:

// checkAllTodo用于全选
    checkAllTodo=(done)=>{
        // 获取原来的todos
        const {todos}=this.state
        // 加工数据
        const newTodos=todos.map((todoObj)=>{
            return {...todoObj,done}
        })
        this.setState({todos:newTodos})
    }

    //checkAllDone用于清除已完成任务 
    checkAllDone=()=>{
        // 获取原来的todos
        const {todos}=this.state
        // 过滤数据
        const newTodos=todos.filter((todoObj)=>{
            //return todoObj.done===false
            return !todoObj.done
        })
        this.setState({todos:newTodos})
    }

子组件Footer调用父组件中的函数:

export default class Footer extends Component {
  // 全选checkbox的回调
  handleCheckAll=(event)=>{
    this.props.checkAllTodo(event.target.checked)
  }

  // 清除已完成任务的回调
  handleCheckAllDone=()=>{
    this.props.checkAllDone()
  }
  
  render() {
    const {todos}=this.props
    // 已完成的个数
    const doneCount=todos.reduce((pre,todo)=>{return pre + (todo.done?1:0)},0)
    // 总数
    const total=todos.length
    return (
        <div className="todo-footer">
            <label>
            <input type="checkbox" onChange={this.handleCheckAll} checked={doneCount===total&&total!==0?true:false}/>  
            </label>
            <span>
            <span>已完成{doneCount}</span> / 全部{total}
            </span>
            <button className="btn btn-danger" onClick={this.handleCheckAllDone}>清除已完成任务</button>
        </div>
    )
  }
}

7.总结TodoList案例

  1. 动态初始化列表,如何确定将数据放在哪个组件的state中?
    某个组件使用:放在其自身的state中
    某些组件使用:放在它们共同的父组件的state中(官方称此操作为状态提升)
  2. 关于父子组件之间通信:
    父–>子传递数据:通过props
    子–>父传递数据:通过props,要求父提前给子传递一个函数
  3. 注意defaultCheckedchecked的区别,类似的还有defaultValuevalue
  4. 状态在哪里,操作状态的方法就在哪里

写在后面

这周的进度比较慢,今天已经周六了,原计划明天看到p100,现在才到p65
因为从周一到周三调了毕设的代码,现在也算跑通了
这两天要赶赶进度了
下一篇是第四章的内容:React ajax

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 尚硅谷张天vue全家桶的资料非常丰富和全面。他的资料包括视频教程、课件、练习代码以及一些额外的学习资料。 首先,他的视频教程非常详细和易于理解。他从Vue的基础概念和语法开始讲解,逐步深入介绍Vue的高级特性和应用场景。他的教学风格非常亲和力,能够将复杂的概念通俗易懂地讲解给学生。每个视频都有配套的课件和代码练习,方便学生理解和实践。 其次,他的课件对于系统学习Vue非常有帮助。课件内容包括了从基础到拓展的知识点,还有一些实际项目实战的案例。课件清晰地列出了每个知识点的要点和示例代码,学生可以跟着课件进行学习和实践。此外,课件中还包含了一些额外的学习资料和参考链接,方便学生深入学习和拓展。 最后,他的练习代码是学生巩固所学知识的重要资源。练习代码包括了各种难度级别的题目,既能够帮助初学者巩固基础知识,也能够挑战有一定经验的学生。学生可以通过做练习代码来巩固所学知识,并检验自己的学习成果。 总的来说,尚硅谷张天vue全家桶的资料非常全面和详细。通过他的教程、课件和练习代码,学生能够系统地学习和掌握Vue的各个方面。无论是初学者还是有一定经验的学生,都能从中获得很大的帮助。 ### 回答2: 尚硅谷张天推出的Vue全家桶资料包括视频教程、PPT课件和源码等多个方面。其中视频教程是最重要的部分,通过张天老师的讲解,学习者可以系统地学习Vue全家桶的使用和开发技巧。这些视频教程内容丰富,从入门到进阶,涵盖了Vue.js、Vue Router、Vuex 等核心知识点,以及如何使用Vue进行项目开发等实际操作。对于初学者来说,这些视频教程可以帮助他们迅速掌握Vue全家桶的基本知识和技能。 除了视频教程,PPT课件也是很有用的学习资料。PPT课件将内容以大纲的形式呈现,可以帮助学习者更好地理解和记忆知识点。在学习过程中,学习者可以根据PPT课件进行复习和巩固,以提高学习效果。 此外,资料中还包括了源码。源码是一个项目或代码的原始本,可以让学习者深入了解Vue全家桶的细节和实现原理。通过阅读源码,学习者可以学到更多关于Vue全家桶的设计思想和开发技巧,为他们在实际项目中解决问题提供参考。 总的来说,尚硅谷张天提供的Vue全家桶资料包含了视频教程、PPT课件和源码三个方面,由浅入深地介绍了Vue全家桶的使用和开发技巧。这些资料对于想要学习和掌握Vue全家桶的开发者来说是非常有价值的。 ### 回答3: 尚硅谷张天的Vue全家桶资料非常全面和丰富。他对Vue框架的教学非常深入,涵盖了从Vue基础知识到高级应用的全方位指导。 在Vue基础知识方面,他讲解了Vue的核心概念、指令和数据绑定等基本概念,并通过实际案例来演示和练习,帮助学员建立起对Vue的基本理解和实践经验。 在Vue进阶应用方面,他着重讲解了Vue的组件化开发,包括组件的定义、组件通信和组件复用等重要知识点。同时,他还教授了Vuex的使用,用于实现Vue项目中的状态管理,以及Vue Router的使用,用于实现前端路由。 此外,他还介绍了Vue的生态系统,如Vue CLI、Vue Devtools等工具的使用,以及与其他第三方库和插件的整合,如Element UI、Axios等。这些知识点的讲解和实操让学员更好地了解和应用Vue相关的工具和技术。 张天的Vue全家桶资料除了理论知识的讲解外,还包含了大量的实际项目实战经验。他通过一系列的实例和案例,讲解了如何使用Vue框架开发实际的前端项目,包括项目的架构设计、代码组织和性能优化等方面。这样的实战训练可以帮助学员更好地掌握Vue框架的应用。 总的来说,尚硅谷张天的Vue全家桶资料内容丰富,深入浅出,给学员提供了一个全面学习和应用Vue框架的平台。无论是初学者还是有一定经验的开发者,都能从中获得很大的收获和提升。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值