• React脚手架介绍和Demo


    源码地址:https://github.com/BLKNjyty/reactstudy

    脚手架

    前言,拿到项目直接npm install 会报错

    在这里插入图片描述

    这是因为之前有缓存,直接

    npm cache clear --force
    
    • 1

    强制清除缓存在进行install

    介绍

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

      • 包含了所有需要的配置(语法检查、jsx编译、devServer…)

      • 下载好了所有相关的依赖

      • 可以直接运行一个简单效果

    2. react提供了一个用于创建react项目的脚手架库: create-react-app

    3. 项目的整体技术架构为: react + webpack + es6 + eslint

    4. 使用脚手架开发的项目的特点: 模块化, 组件化, 工程化

    步骤

    第一步,全局安装:npm i -g create-react-app

    第二步,切换到想创项目的目录,使用命令:create-react-app hello-react

    第三步,进入项目文件夹:cd hello-react

    第四步,启动项目:npm start

    项目结构

    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库的支持)

    组件化

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

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

    3. 实现动态组件

    3.1动态显示初始化数据

    ​ 3.1.1 数据类型

    ​ 3.1.2 数据名称

    ​ 3.1.2 保存在哪个组件?

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

    todo列表案例

    此案例不涉及css的编写,直接使用教程提供的css样式

    划分界面、加入静态效果

    界面分为header,list,item和footer四部分。

    其中head是头部的输入框,item是每一个代办事项,list是item的集合展示,foot是最下面的全选、删除所选等功能。

    export default 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:false}
        ]
        }
        render(){
            return (
            	<div className="todo-container">
                	<div className="todo-warp">
                		<Header/>
                		<List todos={todos}/>
                		<Footer todos={todos}/>
                	</div>
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    export default class Header extends Component{
        render(){
            return(
            	<div className="todo-header">
                	<input type="text" placeholder="请输入你的任务名称,按回车键确定">
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    export default class List extends Component{
        render(){
            const {todos}=this.props
            return(
            	<ul className="todo-main">
                	{
                		todos.map(todo=>{
                				return <Item key={todo.id} {...todo}>
                			}			
            			)
                	}
                </ul>
            )    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    export default Item extends Component{
        render(){
            const {id,name,done}=this.props
            return(
            	<li>
                	<label>
                		<input type="checkbox" checked={done}>
                		<span>name</span>
                	</label>
        			<button className="btn btn-danger">删除</buttton>
                </li>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    export default class Footer extends Component{
        render(){
            const {todos}=this.props
            return(
            	<div className="todo-footer">
                	<label>
                		<input type="checkbox"/ checked=true>
                	</label>
                	<span>
                		<span>已完成{xxx}</span>/全部{xxx}
                	</span>
    				<button className="btn btn-danger">清楚已完成任务</button>
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    实现动态效果

    item的选中变色、删除功能、勾选改变状态

    export default Item extends Component{
        state={mouse:false}
        //添加鼠标移出、移出的item框效果
        handleMouse=(flag)=>{
            return ()=>{
                this.setState({mouse:flag})
            }
        }
        //TODO的内容在父组件APP里面,子孙组件删除父组件的内容,可以使用父组件传递给子组件的函数(APP-list-item)
        handleDelete=(id)=>{
           if(window.confirm('确定删除吗?')){
    			this.props.deleteTodo(id)
    		}
        }
        //勾选或者取消勾选的时候,done值跟随改变
        handleCheck=(id)=>{
            return (event)=>{
                this.props.updateTodo(id,event.target.checked)
            }
        }
        
        render(){
            const {id,name,done}=this.props
            return(
            	<li style={{background:mouse?'#ddd':'white'}} onMouseEnter={this.handleMouse(true)} onMouseLeave={this.handleMouse(false)}>
                	<label>
                		<input type="checkbox" checked={done} onChange={this.handleCheck(id)}>
                		<span>name</span>
                	</label>
        			<button onClick={()=>this.handleDelete(id)} className="btn btn-danger" display:mouse?'block':'none'>删除</buttton>
                </li>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    export default 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:false}
        	]
        }
    	//删除具体某个item
    	deleteTodo=(id)=>{
            const {todos}=this.state
            const newTodos = todos.filter((todo)=>{
             	return todo.id!==id   
            	}
            )
            this.setState({todos:newTodos})
        }
        //更新一个item的状态
        updateTodo=(id,done)=>{
            const {todos}=this.state
            const newTodos=todos.map((todoObj)=>{
                	if(todoObj.id===id)return {...todoObj,done}
                	else return todoObj
            	}
            )
            this.setState({todos:newTodos})
        }
        
        render(){
            return (
            	<div className="todo-container">
                	<div className="todo-warp">
                		<Header/>
                		<List todos={todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo}/>
                		<Footer todos={todos}/>
                	</div>
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    export default class List extends Component{
        render(){
            const {todos,deleteTodo,updateTodo}=this.props
            return(
            	<ul className="todo-main">
                	{
                		todos.map(todo=>{
                				return <Item key={todo.id} {...todo} updateTodo={updateTodo} deleteTodo={deleteTodo} >
                			}			
            			)
                	}
                </ul>
            )    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    header中添加任务功能

    export default class Header extends Component{
        handleKeyUp=(event)=>{
            const {keyCode,target}=event
            if(keyCode!=13)return
            if(target.value.trim(0=)==''){
            	alert("输入不能为空")
                return
            }
        	const todoObj={id:nanoid(),name:target,done:false}
            //同上,子组件想传递信息给父组件,调用父组件传递给子组件的函数即可
            this.props.addTodo(todoObj)
    		target.value=''
        }
        render(){
            return(
            	<div className="todo-header">
                	<input onKeyUp={this.handleKeyUp} type="text" placeholder="请输入你的任务名称,按回车键确定">
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    export default 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:false}
        	]
        }
    	//删除具体某个item
    	deleteTodo=(id)=>{
            const {todos}=this.state
            const newTodos = todos.filter((todo)=>{
             	return todo.id!==id   
            	}
            )
            this.setState({todos:newTodos})
        }
        //添加一个item
        addTodo=(todoObj)=>{
        	const {todos}=this.state
            const newTodos=[todoObj,...todos]
            this.setState({todos:newTodos})
        }
        	//updateTodo用于更新一个todo对象
    	updateTodo = (id,done)=>{
    		//获取状态中的todos
    		const {todos} = this.state
    		//匹配处理数据--id一样则复制一个并替换其中的done属性,如果id不一样则直接返回
    		const newTodos = todos.map((todoObj)=>{
    			if(todoObj.id === id) return {...todoObj,done}
    			else return todoObj
    		})
    		this.setState({todos:newTodos})
    	}
        
        render(){
            return (
            	<div className="todo-container">
                	<div className="todo-warp">
                		<Header addTodo={this.addTodo}/>
                		<List todos={todos} deleteTodo={this.deleteTodo} updateTodo={this.updateTodo}/>
                		<Footer todos={todos}/>
                	</div>
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    Footer的显示,全选功能

    export default class Footer extends Component{
        //将父组件的item的done全部变为true或者false
        handleCheckAll=(event)=>{
            this.props.checkAllTodo(event.target.checked)
        }
        //清除已完成的任务
        handleClearAllDone=()=>{
            this.props.clearAllDone()
        }
        
        render(){
            const {todos}=this.props
            const doneCount=todos.reduce((pre,todo)=>pre+(todo.done?1:0),0)
            const total=todos.length
            return(
            	<div className="todo-footer">
                	<label>
                		<input type="checkbox"/ onChange={this.handleCheckALL} checked=true>
                	</label>
                	<span>
                		<span>已完成{doneCount}</span>/全部{total}
                	</span>
    				<button onClick={this.handleClearAllDone} className="btn btn-danger" >清楚已完成任务</button>
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    export default 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:false}
        	]
        }
    	//删除具体某个item
    	deleteTodo=(id)=>{
            const {todos}=this.state
            const newTodos = todos.filter((todo)=>{
             	return todo.id!==id   
            	}
            )
            this.setState({todos:newTodos})
        }
        //添加一个item
        addTodo=(todoObj)=>{
        	const {todos}=this.state
            const newTodos=[todoObj,...todos]
            this.setState({todos:newTodos})
        }
        	//updateTodo用于更新一个todo对象
    	updateTodo = (id,done)=>{
    		//获取状态中的todos
    		const {todos} = this.state
    		//匹配处理数据--id一样则复制一个并替换其中的done属性,如果id不一样则直接返回
    		const newTodos = todos.map((todoObj)=>{
    			if(todoObj.id === id) return {...todoObj,done}
    			else return todoObj
    		})
    		this.setState({todos:newTodos})
    	}
        //全选、全不选
        checkAllTodo=(done)=>{
            const {todos}=this.state
            const newTodos=todos.map((todoObj)=>{
                return {...obj,done}
            }
            )
            this.setState({todos:newTodos})
        }
        //清除所有已完成的任务
        clearAllDone=()=>{
            const {todos}=this.state
            const newTodos=todos.filter((todoObj)=>{
                return !todoObj.done
            }
            )
            this.setState({todos:newTodos})
        }
        
        render(){
            return (
            	<div className="todo-container">
                	<div className="todo-warp">
                		<Header addTodo={this.addTodo}/>
                		<List todos={todos} deleteTodo={this.deleteTodo} updateTodo={this.updateTodo}/>
                		<Footer todos={todos} checkAllTodo={this.checkAllTodo} clearAllDone={this.clearAllDone}/>
                	</div>
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    声明,本文内容参考b 站 尚硅谷视频。链接

  • 相关阅读:
    openEuler 22.03 LTS SP3(华为欧拉)一键安装 Oracle 12CR2 RAC(220118) 数据库
    基于吉萨金字塔建造优化的BP神经网络(分类应用) - 附代码
    Stable Diffusion 免费升级 SDXL 1.0,哪些新特性值得关注?体验如何?5 分钟带你体验!
    JavaScript关于对象的小挑战
    【Web】标准文档流
    在springboot中整合mybatis配置流程!
    C++--哈希思想的应用--位图--布隆过滤器的介绍--1112
    诠释韧性增长,知乎Q3财报里的社区优势和商业化价值
    Property ‘proxy‘ does not exist on type ‘ComponentInternalInstance | null‘.ts
    【算法系列】卡尔曼滤波算法
  • 原文地址:https://blog.csdn.net/weixin_43604021/article/details/126241977