【react实战小项目:笔记】用React 16写了个订单页面

news2024/12/25 14:44:47

视频地址

React 16 实现订单列表及评价功能

简介:React 以其组件化的思想在前端领域大放异彩,但其革命化的前端开发理念对很多 React 初学者来说, 却很难真正理解和应用到真实项目中。本课程面向掌握了 React 基础知识但缺乏实战经验的开发者, 选取典型实战案例,基于 React 16 开发,介绍了从项目创建、到组件划分、再到组件及页面逻辑实现的开发流程,帮助缺乏实战经验的人掌握 React 开发的基本思想和理念。

课程大纲

  • 课程综述
  • React 基础知识回顾
  • 订单列表及评价案例实现
  • 课程总结

面向用户

  • 具备 React 基础
  • 缺少项目实战经验
  • 初、中级前端开发者或前端爱好者

课程目标

  • 掌握 React 项目的开发流程
  • 理解和应用 React 组件化的思想

开发环境

  • React 16.4.2
  • Nodejs (v8.2.1)
  • NPM (v6.3.0)
  • Visual Studio Code

React 简介

  • 构建用户界面的 JavaScript 库
  • 声明式的视图层
  • 组件为基础

React 基础知识回顾

  • JSX
  • PropsState
  • 组件生命周期
  • 列表和 Keys
  • 事件处理 onClick={}
  • 表单 Forms

使用 create-react-app 创建项目结构

实战案例

  • 项目结构创建
  • 页面组件划分
  • 页面组件实现
  • 获取服务器数据

项目结构创建

创建-响应-应用程序(npm5.2 以上)

create-react-app(npm 5.2+)
npx create-react-app my-order

课程须知

  • 了解基本的 React 知识

老师告诉你能学到什么?

  1. create-react-app 脚手架的使用Create React App 中文文档
  2. React 项目开发流程
  3. 组件划分方法
  4. 组件间的通讯
  5. 列表渲染
  6. 组件事件处理
  7. React 项目中的数据请求

第 1 章 课程介绍

课程介绍,案列效果演示,开发环境准备。

React 基本概念和主要特点介绍:

  • JSX
  • propsstate
  • 生命周期
  • 事件绑定
  • 列表渲染

第 2 章 实战案例讲解

介绍

  • 如何使用脚手架创建 React 项目
  • React 项目中页面组件的划分方法
  • 组件间的通讯
  • 组件列表的渲染
  • 使用 fetch 获取接口数据
  • 以及组件的事件绑定

第 3 章 课程总结

  • 回顾案例和涉及的 React 知识点。

个人实战截图

在这里插入图片描述

项目目录

在这里插入图片描述

publick/mock/json

[
  {
    "id": 1,
    "shop": "创意园区",
    "picture": "https://inews.gtimg.com/newsapp_bt/0/12886421894/641",
    "product": "百香果(冷饮)1扎",
    "price": 19.9,
    "isCommented": false
  },
  {
    "id": 2,
    "shop": "老默之家",
    "picture": "https://n.sinaimg.cn/sinacn07/224/w640h384/20181126/c2d3-hpevhck6865027.jpg",
    "product": "想吃鱼了",
    "price": 39.9,
    "isCommented": true
  },
  {
    "id": 3,
    "shop": "大吉大利店",
    "picture": "https://img1.baidu.com/it/u=4204641963,3545807278&fm=253&fmt=auto&app=138&f=JPEG?w=537&h=500",
    "product": "今晚吃鸡",
    "price": 49.9,
    "isCommented": false
  }
]

compoents/APP/index.js

import React, { Component } from 'react';
import OrderList from '../OrderList';
import Header from '../Header'
import './style.css';

function App() {
  return (
    <div className="App">
      <Header></Header>
      <OrderList />
    </div>
  );
}

export default App;

compoents/APP/style.css

* {
  margin: 0;
  padding: 0
}

compoents/Header/index.js

import React, { Component } from 'react';
import './style.css'
class Header extends Component {
  render() {
    return (
      <div>
         <div className='my_order_title'>我的订单</div>
      </div>
    );
  }
}

export default Header;

compoents/Header/style.css

.my_order_title {
  background:rgb(229,29,52);
  color: white;
  text-align: center;
  padding: 10px 0;
}

compoents/OrderItem/index.js

import React, { Component } from 'react';
// import logo from '../../logo.svg'
// import goodImg from '../../assets/images/good.jpg'
import './style.css'

class OrderItem extends Component {
  constructor(props) {
    super(props);
    this.state = {
      editing: props.data.editing || false,
      stars: props.data.stars || 0,
      comment: props.data.comment || ''
    }
  }
  render() {
    const { picture, product, shop, price, isCommented } = this.props.data
    return (
      <div>
        <div className='order_item'>
            <div className='info_item'>
              <img className='img' src={picture} alt='' />

              <div>
                <div className="good_product">{product}</div>
                <div className="good_shop">{shop}</div>
                <div className="good_price">{price}</div>
              </div>
            </div>

            <div>
              {
                isCommented 
                ? <div className="un_comment_box" onClick={this.handleOpenEditArea}>评价</div>
                : <div className="had_comment_box">已评价</div>
              }
            </div>
            {/* <div className={isCommented ? 'un_comment_box' : 'had_comment_box'}>{isCommented? '评价': '已评价'}</div> */}
          </div>

        <div>{this.state.editing ? this.renderEditArea() : null}</div>
      </div>

    );
  }

  renderEditArea() {
    return (
      <div className='order_comment_box'>
        <textarea 
          onChange={this.handleCommentChange}
          value={this.state.comment}
          rows={4} 
          className='order_comment_text' />
        {this.renderStars()}
        <div className='btn_box'>
          <div className='order_submit' onClick={this.handleSumbitComment}>提交</div>
          <div className='order_cancel' onClick={this.handleCancelComment}>取消</div>
        </div>

      </div>
    )
  }

  renderStars() {
    const { stars } = this.state;
    return (
      <div>
        {
          [1, 2, 3, 4, 5].map((item,index) => {
            const lightClass = stars >= item ? 'orderItem__star--light' : ''
            return (
              <span className={"orderItem__star " + lightClass} key={index} onClick={this.handleClickStars.bind(this, item)}></span>
            )
          })
        }
        
      </div>
    )
  }

  handleOpenEditArea = () => {
    console.log('this.props.data.editing',this.props.data.editing)
    this.setState({
      // editing: !this.props.data.editing
      editing: !this.state.editing
    })
  }

  handleCommentChange = (e) => {
    this.setState({
      comment: e.target.value
    })
  }

  handleClickStars = (stars) => {
    this.setState({
      stars : stars
    })
  }

  handleCancelComment = () => {
    this.setState({
      editing : false,
      stars: this.props.data.stars || 0,
      comment: this.props.data.comment || ''
    })
  }

  handleSumbitComment = () => {
    const { id } = this.props.data;
    const { comment, stars } = this.state
    this.setState({
      editing : false,
    })
    this.props.onSubmit(id, comment, stars)
  }
}

export default OrderItem;

compoents/OrderItem/style.css

.order_item {
  display: flex;
  padding: 12px;
  justify-content: space-between;
  align-items: flex-end;
}

.info_item {
  display: flex;
}
.img_item {
  width: 65px;
  height: 65px;
}

.img {
  width: 65px;
  height: 65px;
  margin-right: 12px;
}

.good_product {
  font-weight: 700;
  margin-bottom: 8px;
}

.good_shop {
  color: #666;
  font-size: 10px;
  margin-bottom: 8px;
}

.good_price {
  color: red;
  font-weight: 700;
}

/* 未评价 */
.un_comment_box {
  padding: 4px 8px;
  color: white;
  background: red;
  border-radius: 6px;
}

/* 已评价 */
.had_comment_box {
  padding: 4px 8px;
  color: white;
  background: #888;
  border-radius: 6px;
}

.order_comment_box {
  width: 100%;
  background: antiquewhite;
  padding: 10px;
}

.order_comment_text {
  width: 90%;
  border: #999;
}

.star_box {
  font-size: 18px;
}

.btn_box {
  display: flex;
}

.order_submit {
  padding: 4px 18px;
  color: white;
  background: red;
  border-radius: 6px;
  margin-right: 10px;
}

.order_cancel {
  padding: 4px 18px;
  color: white;
  background: #888;
  border-radius: 6px;
}

.light {
  background: crimson;
}

.orderItem__star{
  color: gray;
  font-size: 25px;
}
.orderItem__star--light{
  color: gold;
  font-size: 25px;
}

compoents/OrderList/index.js

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


class OrderList extends Component {

  constructor(props) {
    super(props)
    this.state = { data: [] }
  }

  componentDidMount() {
    fetch('/mock/orders.json').then(res => {
      if(res.ok) {
        res.json().then(data => {
          this.setState({
            data
          })
        })
      }
    })
  }

  render() {
    return (
      <div>
        {
          this.state.data.map(item=>{
            return <OrderItem key={item.id} data={item} onSubmit={this.handleSubmit} />
          })
        }
        
      </div>
    );
  }

  handleSubmit = (id, comment, stars) => {
    const newData = this.state.data.map(item => {
      return item.id === id ? 
      {
        ...item, comment, stars, isCommented: true
      }
      : item
    })
    this.setState({
      data: newData
    })
  }
}

export default OrderList;

项目小结

  1. 主要跟着写核心的逻辑代码
  2. 样式和数据可以自己造
  3. 总体上难度不大~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/352790.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

状态机分析

写在前面 状态机是指某事物具有有限状态&#xff0c;且在这些状态之间相互转换的抽象&#xff0c;比如门的开是一个状态&#xff0c;关又是一个状态。本文就一起来看下。 1&#xff1a;状态机的术语 1.1&#xff1a;state 状态&#xff0c;即当前所处的状态&#xff0c;如汽…

电子技术——内部电容效应以及MOS与BJT的高频响应模型

电子技术——内部电容效应以及MOS与BJT的高频响应模型 耦合和旁路电容决定了放大器的低频响应&#xff0c;同时内部电容效应决定了放大器的高频响应。本节&#xff0c;我们简单简单介绍一下内部电容效应&#xff0c;并且更重要的是如何在小信号模型中模型化内部电容效应。 MOS…

C语言操作符经典例题

一、选择题 1、下面哪个是位操作符&#xff1a;&#xff08; &#xff09; A.& B.&& C.|| D.! 答案解析&#xff1a; 答案&#xff1a;A A正确&#xff0c;&——按&#xff08;二进制&#xff09;位与&#xff0c;对应的二进制位&#xff1a;有0则0&#…

将python代码封装成c版本的dll动态链接库

前言 将python程序打包成DLL文件&#xff0c;然后用C调用生成的DLL文件&#xff0c;这是一种用C调用python的方法&#xff0c;这一块比较容易遇到坑。网上关于这一块的教程不是很多&#xff0c;而且大部分都不能完全解决问题。我在傻傻挣扎了几天之后&#xff0c;终于试出了一个…

第八章认识 Vue.js基础

vue.js 是一套用于构建用户界面的渐进式前端框架 vue.js 核心实现&#xff1a; 相应式的数据绑定&#xff1a;当数据发生改变&#xff0c;视图可以自动更新&#xff0c;不用关心DOM操作&#xff0c;而转型数据库操作 可组合的视图组件&#xff1a;把视图按照功能切分成若干的…

vr电力刀闸事故应急演练实训系统开发

电力事故是在电力生产和输电过程中可能发生的意外事件&#xff0c;它们可能会对人们的生命财产安全造成严重的威胁。因此&#xff0c;电力事故应急演练显得尤为重要。而VR技术则可以为电力事故应急演练提供一种全新的解决方案。 在虚拟环境中&#xff0c;元宇宙VR会模拟各种触电…

07 react+echart+大屏

reactechart大屏大屏ECharts 图表实际步骤React Typescript搭建大屏项目&#xff0c;并实现屏幕适配flexible rem实现适配1. 安装插件对echarts进行的React封装&#xff0c;可以用于React项目中&#xff0c;支持JS、TS如何使用完整例子官网参考大屏 ECharts 图表 ECharts 图…

【Java基础】泛型(二)-泛型的难点:通配符

本文将尝试将通配符和泛型中的继承&#xff0c;多态一并讲解 关于泛型中继承的注意事项 因为Integer、Double继承了Number&#xff0c;根据多态性&#xff0c;以下语句是合法的 Number n new Integer(10); // OK, 父类引用变量可以指向子类对象 n 2.9 // OK&#xff0c;n实…

Mac-Charles

Charles是什么 HTTP代理服务器&#xff0c;HTTP监视器 Charles可以当作一个代理服务器 当浏览器链接这个代理服务器的时候 Charles会监控浏览器发出和接收的所有数据(reques,response,HTTP Headers(cookies和cash)) 反转代理器 Charles主要功能、 1.SSL代理 2.模拟慢速网络…

双目立体视觉:SAD算法

算法原理SAD(Sum of absolute differences)是一种图像匹配算法。基本思想&#xff1a;差的绝对值之和。此算法常用于图像块匹配&#xff0c;将每个像素对应数值之差的绝对值求和&#xff0c;据此评估两个图像块的相似度。该算法快速、但并不精确&#xff0c;通常用于多级处理的…

如何在Power Virtual Agents中实现身份验证

今天我们介绍一下如何通过身份验证的方式来使用Power Virtual Agents。首先进入“Microsoft 365-管理-Azure Active Directory管理中心”。 进入“Azure Active Directory管理中心”后选择“Azure Active Directory”中的“应用注册”-“新注册”。 输入新创建的应用程序名称后…

XXL-JOB分布式任务调度框架(一)-基础入门

文章目录1.什么是任务调度2.常见定时任务方案2.1. 传统定时任务方案示例2.2. 缺点分析3.什么是分布式任务调度&#xff1f;3.1. 并行任务调度3.2. 高可用3.3. 弹性扩容3.4. 任务管理与监测4.市面上常见的分布式任务调度产品5.初识xxl-job6.xxl-job架构设计6.1.设计思想6.2.架构…

程序人生 - 学习和分享

文章目录记于 230217学习安排泛学AI 和 未来记于 230217 刚入行时&#xff0c;经常看到技术博客中&#xff0c;博主们分享生活&#xff0c;比如相亲、上班生活&#xff0c;甚至还有人发结婚照。这个栏目通常被称为&#xff1a;程序人生。 这个现象已经很久没看到了&#xff0c…

BFC 是什么

在页面布局的时候&#xff0c;经常出现以下情况&#xff1a; 这个元素高度怎么没了&#xff1f;这两栏布局怎么没法自适应&#xff1f;这两个元素的间距怎么有点奇怪的样子&#xff1f;...... 原因是元素之间相互的影响&#xff0c;导致了意料之外的情况&#xff0c;这里就涉及…

吴恩达深度学习笔记(八)——卷积神经网络(上)

一、卷积相关 用一个ff的过滤器卷积一个nn的图像&#xff0c;假如padding为p&#xff0c;步幅为s&#xff0c;输出大小则为&#xff1a; [n2p−fs1][n2p−fs1][\frac{n2p-f}{s}1][\frac{n2p-f}{s}1][sn2p−f​1][sn2p−f​1] []表示向下取整&#xff08;floor) 大部分深度学习…

Unreal Engine04:Visual Studio和Editor的协同开发

写在前面 这里主要是记录一下Visual Studio和Editor之间的关系和如何使用它们进行UE4协同开发。 一、启动 1. 先启动Visual Studio再启动Editor (1) 打开项目根目录下的xxx.sln解决方案&#xff0c;即可启动Visual Studio&#xff0c;这个是和普通的C项目打开方式相同的&…

2023美国大学生数学建模竞赛C题思路解析(含代码+数据可视化)

以下为2023美国大学生数学建模竞赛C题思路解析&#xff08;含代码数据可视化&#xff09;规则&#xff1a;猜词&#xff0c;字母猜对&#xff0c;位置不对为黄色&#xff0c;位置对为绿色&#xff0c;两者皆不对为灰色。困难模式下的要求&#xff1a;对于猜对的字母&#xff08…

RBAC权限模型

什么是RBAC权限模型&#xff1f; RBAC是基于角色的访问控制&#xff0c;在RBAC中&#xff0c;权限与角色相关联&#xff0c;用户通过成为适当角色的成员而得到这些角色的权限。 1.0级 用户、角色、权限 2.0 权限分级 公司>部门>小组 2.1 权限继承 ps: 这个人是一个小组长…

Java调用Selenium实现自动化测试

Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。支持的浏览器包括IE&#xff08;7, 8, 9, 10, 11&#xff09;&#xff0c;Mozilla Firefox&#xff0c;Safari&#xff0c;Google Chrome&#xff0c;Opera等。 Selenium简介 Selenium是一个用于Web应用…

Spring MVC 之Tomcat启动流程

从web.xml说起在开始 Spring MVC 的分析之前&#xff0c;先来聊一聊 Java 初学者接触的最多的 Java Web 基础。还记得我的第一个 Web 工程是由 Servlet、Velocity 和 Filter 来完成的&#xff0c;那时几乎所有人都是根据 Servlet、JSP 和 Filter 来编写自己的第一个 Hello Worl…