React 全栈体系(五)

第三章:React 应用(基于 React 脚手架)

一、使用 create-react-app 创建 react 应用

1. react 脚手架

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

2. 创建项目并启动

  • 第一步,全局安装:npm i -g create-react-app
  • 第二步,切换到想创项目的目录,使用命令:create-react-app hello-react
  • 第三步,进入项目文件夹:cd hello-react
  • 第四步,启动项目:npm start
bash 复制代码
# 新版安装方法!

npx create-react-app myapp
cd my-app
npm start

3. react 脚手架项目结构

bash 复制代码
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. 功能界面的组件化编码流程(通用)

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

5. 代码


javascript 复制代码
/* src/index.js */
//引入react核心库
import React from 'react'
//引入ReactDOM
import ReactDOM from 'react-dom'
//引入App组件
import App from './App'

//渲染App到页面
ReactDOM.render(<App/>,document.getElementById('root'))
javascript 复制代码
/* src/App.jsx */
//创建"外壳"组件App
import React,{Component} from 'react'
import Hello from './components/Hello'
import Welcome from './components/Welcome'

//创建并暴露App组件
export default class App extends Component{
	render(){
		return (
			<div>
				<Hello/>
				<Welcome/>
			</div>
		)
	}
}
javascript 复制代码
/* src/components/Hello/index.jsx */
import React,{Component} from 'react'
import hello from './index.module.css'

export default class Hello extends Component{
	render(){
		return <h2 className={hello.title}>Hello,React!</h2>
	}
}
css 复制代码
/* src/components/Hello/index.module.css */
.title{
	background-color: orange;
}
javascript 复制代码
/* src/components/Welcome/index.jsx */
import React,{Component} from 'react'
import './index.css'

export default class Welcome extends Component{
	render(){
		return <h2 className="title">Welcome</h2>
	}
}
css 复制代码
/* src/components/Welcome/index.css */
.title{
	background-color: skyblue;
}

二、组件的组合使用 - TodoList

  • 功能:组件化实现此功能
    • 显示所有 todo 列表
    • 输入文本, 点击按钮显示到列表的首位, 并清除输入的文本
  • 静态页面源码
html 复制代码
<!-- index.html -->
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>React App</title>

  <link rel="stylesheet" href="index.css">
</head>
<body>
<div id="root">
  <div class="todo-container">
    <div class="todo-wrap">
      <div class="todo-header">
        <input type="text" placeholder="请输入你的任务名称,按回车键确认"/>
      </div>
      <ul class="todo-main">
        <li>
          <label>
            <input type="checkbox"/>
            <span>xxxxx</span>
          </label>
          <button class="btn btn-danger" style="display:none">删除</button>
        </li>
        <li>
          <label>
            <input type="checkbox"/>
            <span>yyyy</span>
          </label>
          <button class="btn btn-danger" style="display:none">删除</button>
        </li>
      </ul>
      <div class="todo-footer">
        <label>
          <input type="checkbox"/>
        </label>
        <span>
          <span>已完成0</span> / 全部2
        </span>
        <button class="btn btn-danger">清除已完成任务</button>
      </div>
    </div>
  </div>
</div>

</body>
</html>
css 复制代码
/* index.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;
}

/*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);
}

/*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;
}
/*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;
}

/*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;
}

1. 静态组件

1.1 index.js

javascript 复制代码
/* src/index.js */
//引入react核心库
import React from 'react'
//引入ReactDOM
import ReactDOM from 'react-dom'
//引入App组件
import App from './App'

//渲染App到页面
ReactDOM.render(<App/>,document.getElementById('root'))

1.2 App

javascript 复制代码
/* src/App.jsx */
//创建"外壳"组件App
import React,{Component} from 'react'
import Header from './components/Header'
import List from './components/List'
import Footer from './components/Footer'
import './App.css'

//创建并暴露App组件
export default class App extends Component{
	render(){
		return (
			<div className="todo-container">
				<div className="todo-wrap">
					<Header/>
					<List />
					<Footer />
				</div>
			</div>
		)
	}
}
css 复制代码
/* src/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;
  }

1.3 Header

javascript 复制代码
/* src/components/Header/index.jsx */
import React, { Component } from 'react'
import './index.css'

export default class Header extends Component {
  render() {
    return (
        <div className="todo-header">
            <input type="text" placeholder="请输入你的任务名称,按回车键确认"/>
        </div>
    )
  }
}
css 复制代码
/* src/components/Header/index.css */
.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);
  }

1.4 List

javascript 复制代码
/* src/components/List/index.jsx */
import React, { Component } from 'react'
import Item from '../Item'
import './index.css'

export default class List extends Component {
  render() {
    return (
        <ul className="todo-main">
          <Item />
          <Item />
          <Item />
          <Item />
          <Item />
        </ul>
    )
  }
}
css 复制代码
/* src/components/List/index.css */
.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;
  }

1.5 Item

javascript 复制代码
/* src/components/Item/index.jsx */
import React, { Component } from 'react'
import './index.css'

export default class Item extends Component {
  render() {
    return (
        <li>
        <label>
            <input type="checkbox"/>
            <span>xxxxx</span>
        </label>
        <button className="btn btn-danger" style={{display: "none"}}>删除</button>
        </li>
    )
  }
}
css 复制代码
/* src/components/Item/index.css */
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;
  }
javascript 复制代码
/* src/components/Footer/index.jsx */
import React, { Component } from 'react'
import './index.css'

export default class Footer extends Component {
  render() {
    return (
        <div className="todo-footer">
        <label>
        <input type="checkbox"/>
        </label>
        <span>
        <span>已完成0</span> / 全部2
        </span>
        <button className="btn btn-danger">清除已完成任务</button>
    </div>
    )
  }
}
css 复制代码
/* src/components/Footer/index.css */
.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;
  }

2. 动态初始化列表

2.1 App

javascript 复制代码
/* src/App.jsx */
//创建"外壳"组件App
import React,{Component} from 'react'
import Header from './components/Header'
import List from './components/List'
import Footer from './components/Footer'
import './App.css'

//创建并暴露App组件
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(){
		const {todos} = this.state
		return (
			<div className="todo-container">
				<div className="todo-wrap">
					<Header/>
					<List todos={todos}/>
					<Footer />
				</div>
			</div>
		)
	}
}

2.2 List

javascript 复制代码
/* src/components/List/index.jsx */
import React, { Component } from 'react'
import Item from '../Item'
import './index.css'

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>
    )
  }
}

2.3 Item

javascript 复制代码
/* src/components/Item/index.jsx */
import React, { Component } from 'react'
import './index.css'

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>
    )
  }
}
相关推荐
xiao-xiang11 分钟前
jenkins-通过api获取所有job及最新build信息
前端·servlet·jenkins
C语言魔术师28 分钟前
【小游戏篇】三子棋游戏
前端·算法·游戏
匹马夕阳2 小时前
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
前端·javascript·vue.js
你熬夜了吗?2 小时前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
screct_demo3 小时前
詳細講一下在RN(ReactNative)中,6個比較常用的組件以及詳細的用法
javascript·react native·react.js
桂月二二8 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062069 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb9 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角9 小时前
CSS 颜色
前端·css
九酒10 小时前
从UI稿到代码优化,看Trae AI 编辑器如何帮助开发者提效
前端·trae