[尚硅谷React笔记]——第3章 React应用(基于React脚手架)

目录:

  1. react脚手架
  2. 创建项目并启动
  3. react脚手架项目结构
  4. 一个简单的Hello组件
  5. 样式的模块化
  6. 功能界面的组件化编码流程(通用)
  7. 组件的组合使用-TodoList  

1.react脚手架

  1. xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目
    1. 包含了所有需要的配置(语法检查、jsx编译、devServer…)
    2. 下载好了所有相关的依赖
    3. 可以直接运行一个简单效果
  2. react提供了一个用于创建react项目的脚手架库: create-react-app
  3. 项目的整体技术架构为:  react + webpack + es6 + eslint
  4. 使用脚手架开发的项目的特点: 模块化, 组件化, 工程化

2.创建项目并启动

  1. 全局安装:npm i -g create-react-app
  2. 切换到想创项目的目录,使用命令:create-react-app hello-react
  3. 进入项目文件夹:cd hello-react
  4. 启动项目:npm start

3.react脚手架项目结构

public ---- 静态资源文件夹

                        favicon.icon ------ 网站页签图标

                        index.html -------- 主页面

                        logo192.png ------- logo

                        logo512.png ------- logo

                        manifest.json ----- 应用加壳的配置文件

                        robots.txt -------- 爬虫协议文件

src ---- 源码文件夹

                        App.css -------- App组件的样式

                        App.js --------- App组件

                        App.test.js ---- 用于给App做测试

                        index.css ------ 样式

                        index.js ------- 入口文件

                        logo.svg ------- logo

                        reportWebVitals.js --- 页面性能分析文件(需要web-vitals库的支持)

                        setupTests.js ---- 组件单元测试的文件(需要jest-dom库的支持)

4.一个简单的Hello组件

Hello.jsx

import React, {Component} from 'react'
import './Hello.css'

export default class Hello extends Component {
    render() {
        return 

hello,react!

} }

Hello.css

.title {
    background-color: orange;
}

Welcome.jsx

import React, {Component} from "react";
import './Welcome.css'

export default class Welcome extends Component {
    render() {
        return 

welcome

} }

Welcome.css

.demo {
    background-color: skyblue;
}

 App.js

import React from 'react'
import Hello from "./components/Hello/Hello";
import Welcome from "./components/Welcome/Welcome";

export default class App extends React.Component {
    render() {
        return (
            
) } }

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render();

 运行结果:

[尚硅谷React笔记]——第3章 React应用(基于React脚手架)_第1张图片

5.样式的模块化 

Hello.jsx

import React, {Component} from 'react'
import hellocss from './Hello.module.css'

export default class Hello extends Component {
    render() {
        return 

hello,react!

} }

Hello.module.css

.title {
    background-color: orange;
}

 Welcome.jsx

import React, {Component} from "react";
import welcomecss from './Welcome.module.css'

export default class Welcome extends Component {
    render() {
        return 

welcome

} }

Welcome.module.css

.title {
    background-color: skyblue;
}

 运行结果:

[尚硅谷React笔记]——第3章 React应用(基于React脚手架)_第2张图片

6.功能界面的组件化编码流程(通用)

  1. 拆分组件: 拆分界面,抽取组件
  2. 实现静态组件: 使用组件实现静态页面效果
  3. 实现动态组件
    1. 动态显示初始化数据
      1. 数据类型
      2. 数据名称
      3. 保存在哪个组件?
    2. 交互(从绑定事件监听开始)

7.组件的组合使用-TodoList  

todoList案例相关知识点

  1. 拆分组件、实现静态组件,注意: className、style的写法
  2. 动态初始化列表,如何确定将数据放在哪个组件的state中?
    1. 某个组件使用放在自身的state中
    2. 某些组件使用:放在他们共同的父组件state中(官方称此操作为:状态提升
  3. 关于父子之间通信:
    1. 【父组件】给【子组件】传递数据:通过props传递
    2. 【子组件】给【父组件】传递数据:通过props传递,要求父提前给子传递
  4. 注意defaultchecked 和 checked的区别,类似的还有: defaultValue 和 value
  5. 状态在哪里,操作状态的方法就在哪里

 Footer.css

/*footer*/
.todo-footer {
    height: 40px;
    line-height: 40px;
    padding-left: 6px;
    margin-top: 5px;
}

.todo-footer label {
    display: inline-block;
    margin-right: 20px;
    cursor: pointer;
}

.todo-footer label input {
    position: relative;
    top: -1px;
    vertical-align: middle;
    margin-right: 5px;
}

.todo-footer button {
    float: right;
    margin-top: 5px;
}

Footer.jsx

import React, {Component} from 'react';
import './Footer.css'

class Footer extends Component {
    handleCheckAll = (event) => {
        this.props.checkAllTodo(event.target.checked)
    }
    handleClearAllDone = () => {
        this.props.clearAllDone()
    }


    render() {
        const {todos} = this.props
        const doneCount = todos.reduce((pre, current) => {
            return pre + (current.done ? 1 : 0)
        }, 0)
        const total = todos.length
        return (
            
已完成{doneCount} / 全部{total}
); } } export default Footer;

Header.css

/*header*/
.todo-header input {
    width: 560px;
    height: 28px;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 4px 7px;
}

.todo-header input:focus {
    outline: none;
    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
}

Header.jsx

import React, {Component} from 'react';
import PropTypes from 'prop-types'
import {nanoid} from "nanoid";
import './Header.css'

class Header extends Component {
    static propTypes = {
        addTodo: PropTypes.func.isRequired
    }

    handleKeyUp = (event) => {
        const {keyCode, target} = event
        if (keyCode != 13) return
        if (target.value.trim() == '') {
            alert('输入不能为空')
            return;
        }
        const todoObj = {id: nanoid(), name: target.value, done: false}
        this.props.addTodo(todoObj)

        target.value = ''
    }

    render() {
        return (
            
); } } export default Header;

Item.css

/*item*/
li {
    list-style: none;
    height: 36px;
    line-height: 36px;
    padding: 0 5px;
    border-bottom: 1px solid #ddd;
}

li label {
    float: left;
    cursor: pointer;
}

li label li input {
    vertical-align: middle;
    margin-right: 6px;
    position: relative;
    top: -1px;
}

li button {
    float: right;
    display: none;
    margin-top: 3px;
}

li:before {
    content: initial;
}

li:last-child {
    border-bottom: none;
}

Item.jsx

import React, {Component} from 'react';
import './Item.css'

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

    handelMouse = (flag) => {
        return () => {
            this.setState({mouse: flag})
        }
    }

    handleCheck = (id) => {
        return (event) => {
            this.props.updateTodo(id, event.target.checked)
        }
    }

    handleDelete = (id) => {
        if (window.confirm('确定删除吗?')) {
            this.props.deleteTodo(id)
        }
    }

    render() {
        const {id, name, done} = this.props
        const {mouse} = this.state
        return (
            
  • ); } } export default Item;

    List.css

    /*main*/
    .todo-main {
        margin-left: 0px;
        border: 1px solid #ddd;
        border-radius: 2px;
        padding: 0px;
    }
    
    .todo-empty {
        height: 40px;
        line-height: 40px;
        border: 1px solid #ddd;
        border-radius: 2px;
        padding-left: 5px;
        margin-top: 10px;
    }

    List.jsx

    import React, {Component} from 'react';
    import PropTypes from "prop-types";
    import Item from "../Item/Item";
    import './List.css'
    
    
    class List extends Component {
        static propTypes = {
            todos: PropTypes.array.isRequired,
            updateTodo: PropTypes.func.isRequired,
            deleteTodo: PropTypes.func.isRequired
        }
    
        render() {
            const {todos, updateTodo, deleteTodo} = this.props
            return (
                
      { todos.map((todo) => { return }) }
    ); } } export default List;

    App.css

    /*base*/
    body {
        background: #fff;
    }
    
    .btn {
        display: inline-block;
        padding: 4px 12px;
        margin-bottom: 0;
        font-size: 14px;
        line-height: 20px;
        text-align: center;
        vertical-align: middle;
        cursor: pointer;
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
        border-radius: 4px;
    }
    
    .btn-danger {
        color: #fff;
        background-color: #da4f49;
        border: 1px solid #bd362f;
    }
    
    .btn-danger:hover {
        color: #fff;
        background-color: #bd362f;
    }
    
    .btn:focus {
        outline: none;
    }
    
    .todo-container {
        width: 600px;
        margin: 0 auto;
    }
    
    .todo-container .todo-wrap {
        padding: 10px;
        border: 1px solid #ddd;
        border-radius: 5px;
    }
    
    
    
    
    
    
    
    
    

    App.js

    import React, {Component} from 'react';
    import './App.css'
    import Header from "./components/Header/Header";
    import Footer from "./components/Footer/Footer";
    import List from "./components/List/List";
    
    class App extends Component {
        //初始化状态
        state = {
            todos: [
                {id: '001', name: '吃饭', done: true},
                {id: '002', name: '睡觉', done: true},
                {id: '003', name: '打代码', done: false},
                {id: '004', name: '逛街', done: true},
            ]
        }
    
        addTodo = (todoObj) => {
            const {todos} = this.state
            const newTodos = [todoObj, ...todos]
            this.setState({todos: newTodos})
        }
    
        updateTodo = (id, done) => {
            const {todos} = this.state
            const newTodos = todos.map((todoObj) => {
                if (todoObj.id === id) {
                    return {...todoObj, done: done}
                } else {
                    return todoObj
                }
            })
    
            this.setState({todos: newTodos})
        }
    
        deleteTodo = (id) => {
            const {todos} = this.state
            const newTodos = todos.filter((todoObj) => {
                return todoObj.id !== id
            })
            this.setState({todos: newTodos})
        }
    
        checkAllTodo = (done) => {
            const {todos} = this.state
            const newTodos = todos.map((todoObj) => {
                return {...todoObj, done: done}
            })
            this.setState({todos: newTodos})
        }
    
        clearAllDone = () => {
            const {todos} = this.state
            const newTodos = todos.filter((todoObj) => {
                return !todoObj.done
            })
            this.setState({todos: newTodos})
        }
    
        render() {
            return (
                
    ); } } export default App;

    index.js

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import App from './App';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render();
    
    

    项目结构:

    [尚硅谷React笔记]——第3章 React应用(基于React脚手架)_第3张图片

    运行结果:

    [尚硅谷React笔记]——第3章 React应用(基于React脚手架)_第4张图片 

    你可能感兴趣的:(#,React,react.js,笔记,javascript)