react基础06--react综合案例-电商网站导航

2023-11-09

1 介绍

继上文 react基础05–react-router 路由, 本文将根据上述01-05小节的基础知识实现一个小型电商网站的基础导航和搜索模型.
分类导航是一个很重要且常见的功能, 常见美团App商品 菜品都是一级导航, 京东、淘宝等商城多为二级甚至三级导航。本文将实现一个基础的商品导航功能, 具体包括一级二级导航、商品展示、查看详情、筛选、搜索 等功能。

2 案例设计模块

2.1 分类导航数据模型设计

结构设计:
电商网站-{电器、服装、玩具、手机}
电器-{冰箱、洗衣机、空调}
服装-{外套、衬衣、裤子}
玩具-{挖掘机、赛车、游戏机}
手机-{华为、小米、苹果}

数据设计(data.json):

{
    "navs": [
        {
            "id": 1,
            "pid": 0,
            "name": "电器"
        }, 
        {
            "id": 2,
            "pid": 1,
            "name": "冰箱"
        }, 
        {
            "id": 3,
            "pid": 0,
            "name": "空调"
        },        
        {
            "id": 4,
            "pid": 0,
            "name": "服装"
        }, 
        {
            "id": 5,
            "pid": 6,
            "name": "外套"
        }, 
        {
            "id": 6,
            "pid": 0,
            "name": "玩具"
        },
        {

            "id": 7,
            "pid": 0,
            "name": "手机"
        }
    
    ], "goods": [
        {
            "id": 1,
            "classify": "3",
            "title": "海尔空调",
            "price": 2000
        },        {
            "id": 2,
            "classify": "3",
            "title": "格力空调",
            "price": 1800
        },
        {
            "id": 3,
            "classify": "7",
            "title": "小米新手机",
            "price": 2990
        },
        {
            "id": 4,
            "classify": "7",
            "title": "华为新手机",
            "price": 3600
        }
    ]
}

2.2 一级分类导航切换高亮效果

vim GoodList01.js

import React, { Component } from 'react';
import axios from 'axios'

export class GoodsList01 extends Component {

  constructor(){
    super();
    this.state = {
      navs: [], //所有分类数据
      goods: [], //所有商品数据,
      selId: 1 //被选中的id
    }
  }

  componentDidMount(){
    axios.get("http://localhost:3000/data.json")
    .then((resp)=>{
      console.log(resp.data)
      this.setState({
        navs: resp.data.navs
      })
    })
  }

  render() {
    const { navs, goods, selId } = this.state;
    return (
      <div>
        {navs.map((item, index) =>{
          if (item.pid === 0){
            return (
              <div 
                key={index}
                style={{color:selId === item.id ? 'red':"#999"}}
                onClick={()=>{
                  this.setState({
                    selId: item.id
                  })
                  }
                }
                >
                {item.name}
              </div>
            )
          }else {
            return (
              <div key={index}>
              </div>
            )
          }
        })}
      </div>
    )
  }
}

export default GoodsList01

结果:
在这里插入图片描述

2.3 显示二级分类导航

vim GoodList01.js

import React from 'react';
import axios from 'axios'

export class GoodsList01 extends React.Component {

  constructor(){
    super();
    this.state = {
      navs: [], //所有分类数据
      goods: [], //所有商品数据,
      selId: 1 //被选中的id
    }
  }

  componentDidMount(){
    axios.get("http://localhost:3000/data.json")
    .then((resp)=>{
      console.log(resp.data)
      this.setState({
        navs: resp.data.navs
      })
    })
  }

  render() {
    const { navs, selId } = this.state;
    return (
      <div>
        <div style={{display:"flex", flexDirection:"row"}}>
        {navs.map((item, index) =>{
          if (item.pid === 0){
            return (
              <div 
                key={index}
                style={{color:selId === item.id ? 'red':"#999"}}
                onClick={()=>{
                  this.setState({
                    selId: item.id
                  })
                  }
                }
                >
                {item.name}&nbsp;
              </div>
            )
          }else {
            return (
              <div key={index}>
              </div>
            )
          }
        })}
        </div>
        <hr />
        {navs.map((item, index)=>{
          if(item.pid === selId){
            return (
              <div key={index}> 
                {item.name}
              </div>
            )
          }else {
            return (
              <div> </div>
            )
          }
        })
        }

      </div>
    )
  }
}
export default GoodsList01

最下面新加一个 navs.map((item, index) 即可

2.4 路由跳转到二级导航的商品列表

vim Nav01.js

import React from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom'

export class Nav01 extends React.Component {

  constructor(){
    super();
    this.state = {
      navs: [], //所有分类数据
      goods: [], //所有商品数据,
      selId: 1 //被选中的id
    }
  }

  componentDidMount(){
    axios.get("http://localhost:3000/data.json")
    .then((resp)=>{
      // console.log(resp.data)
      this.setState({
        navs: resp.data.navs
      })
    })
  }

  render() {
    const { navs, selId } = this.state;
    return (
      <div>
        <div style={{display:"flex", flexDirection:"row"}}>
        {navs.map((item, index) =>{
          if (item.pid === 0){
            return (
              <div 
                key={index}
                style={{color:selId === item.id ? 'red':"#999"}}
                onClick={()=>{
                  this.setState({
                    selId: item.id
                  })
                  }
                }
                >
                {item.name}&nbsp;
              </div>
            )
          }else {
            return (
              <div key={index}>
              </div>
            )
          }
        })}
        </div>
        <hr />
        {navs.map((item, index)=>{
          if(item.pid === selId){
            return (
              <Link key={index} to={`/list/${item.id}`}>
                <div key={index}> 
                  {item.name}
                </div>
              </Link>
            )
          }else {
            return (
              <div key={index}> 
              </div>
            )
          }
        })
        }

      </div>
    )
  }
}

export default Nav01

vim GoodsList.js

import React, { Component } from 'react';
import axios from 'axios';

export class GoodsList extends Component {
  constructor() {
    super();
    this.state = {
      goods: []
    }
  }

  UNSAFE_componentWillMount(){
    // console.log(this.props)
    let id = this.props.match.params.id;
    console.log(id)
    axios.get("http://localhost:3000/data.json")
    .then((resp)=>{
      let goodsList = resp.data.goods;
      let goods = [];
      goodsList.map((item)=>{
          if(item.classify === id){
            goods.push(item)
          }
          return goods
      })
      this.setState({
        goods
      })
    })
  }
    
  render() {
    return (
        <div>
          <div onClick={()=>{
            window.history.back()
          }}>返回</div>
          This is GoodsList!
          {this.state.goods.map((item, index)=>{
            return (
              <div key={index}>
                {item.title},{item.price}
              </div>
            )
          })}
        </div>
    )
  }
}

export default GoodsList

vim App.js

import React from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import GoodsList from "./pages/GoodsList";
import Nav01 from "./pages/Nav01";

class App extends React.Component{

    render(){
        return (
            <BrowserRouter>
                <Switch>
                    <Route path="/list/:id" component={GoodsList} />
                    <Route exact path="/" component={Nav01} />
                </Switch>
            </BrowserRouter>
        )
    }
}

export default App

结果:
在这里插入图片描述
点击 手机-小米手机
在这里插入图片描述

2.5 商品搜索

vim Search.js

import React, { Component } from 'react';
import axios from 'axios';

export class Search extends Component {
    constructor(){
        super();
        this.state = {
          goods: [], //所有商品数据,
          inputValue: '',
          resultList: []
        }
      }
    
    componentDidMount(){
    axios.get("http://localhost:3000/data.json")
    .then((resp)=>{
        // console.log(resp.data)
        this.setState({
        goods: resp.data.goods
        })
    })
    }

    render(){
        return (
        <div>
            <div >
            <input value={this.state.inputValue} onChange={(e)=>{
                this.setState({
                    inputValue: e.target.value
                })
            }}/>
            <button onClick={this.search.bind(this)}>搜索</button>
            </div>
            {this.state.resultList.map((item, index)=>{
                return (
                    <div key={index}> 
                        {item.title},¥{item.price}
                    </div>
                )
            })}
        </div>
        )
    }

    search(){
        let keyword = this.state.inputValue;
        console.log(keyword)
        let goods =  this.state.goods;
        let resultList = []
        goods.map((item)=>{
            if(item.title.includes(keyword)){
                resultList.push(item)
            }
        })
        this.setState({resultList})
    }
}

export default Search

vim Nav01.js

 render() {
    const { navs, selId } = this.state;
    return (
      <div>
        <Link to={`/search`}>搜索</Link>
        <div style={{display:"flex", flexDirection:"row"}}>
        {navs.map((item, index) =>{
		***
		}}
		</div>
	  </div>
	)
 }

vim App.js

class App extends React.Component{

    render(){
        return (
            <BrowserRouter>
                <Switch>
                    <Route path="/search" component={Search}></Route>
                    <Route path="/list/:id" component={GoodsList} />
                    <Route exact path="/" component={Nav01} />
                </Switch>
            </BrowserRouter>
        )
    }
}

结果:
主界面
在这里插入图片描述
点击搜索界面
在这里插入图片描述
搜索产品
在这里插入图片描述

3 注意事项

  1. 安装包
    npm i axios --save
    npm i react-router-dom@5.2.0 --save
    
  2. 错误
    Array.prototype.map() expects a return value from arrow function 
    
    goodsList.map((item)=>{
           if(item.classify === id){
             goods.push(item)
           }
           return goods
       })
    
  3. child in a list should have a unique “key” prop
    {navs.map((item, index)=>{
          if(item.pid === selId){
            return (
              <Link key={index} to={`/list/${item.id}`}>
                <div key={index}> 
                  {item.name}
                </div>
              </Link>
            )
          }else {
            return (
              <div key={index}> 
              </div>
            )
          }
        })
        }
    
  4. 当前选中二级分类后产品在 /list/{number} 页面显示, 也可以在Nave01.js 下面再加一层展示具体产品列表的功能。
  5. 当前只是模拟商城的基础功能,后续可以在此基础上新增 登录注册、加购物车流程;也可以通过本案例学习完成一个 TodoList 小应用。

4 说明

软件版本:
node 16.13.1
create-react-app 5.0.0
react-router-dom@5.2.0
axios 0.25.0
参考文档:
React基础入门+综合案例
react 官网
React基础入门教程
withRouter’ is not exported from ‘react-router-dom’

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

react基础06--react综合案例-电商网站导航 的相关文章

随机推荐

  • 苏州吴江区实现首单跨区域数字人民币试点场景应用

    作为数字人民币试点的首批城市 苏州一直在数字人民币应用场景的落地方面进展迅速 其中 苏州相城区在全市率先开展数字人民币场景建设及试点 截至目前 已开放试点场景7500余个 占全市总数近50 并在全国率先落地交通补贴批量代发 房屋契税缴纳 智
  • python num循环怎么从1开始

    如何实现python for循环从1开始 range 函数的作用和用法 编写一个从数值1开始的循环 执行后得到的结果 其他注意事项
  • 在OTFS学习中的一些总结

    双选特性 多径传播 gt 时延 gt 频率选择性 时延的倒数为相干带宽 在频域内信道相应的幅值大概保持不变的一段频率称为相干带宽 当信号的带宽小于相干带宽 或者说信号的传输时间 周期 大于时延拓展 信号之间没有干扰 我们认为信号是没有失真的
  • Win10下Anaconda使用conda activate激活环境出错

    直接输入conda activate pytorch 报如下错误 解决方法 1 在base路径下先输入activate 提示如下 2 再输入conda activate base 激活base环境 3 在输入conda activate p
  • [python知识] 爬虫知识之BeautifulSoup库安装及简单介绍

    一 前言 在前面的几篇文章中我介绍了如何通过Python分析源代码来爬取博客 维基百科InfoBox和图片 其文章链接如下 python学习 简单爬取维基百科程序语言消息盒 Python学习 简单网络爬虫抓取博客文章及思想介绍 python
  • awk使用shell变量,shell获取awk中的变量值

    awk使用shell变量 shell获取awk中的变量值 2012 04 13 09 36 28 分类 LINUX 字号 订阅 原文 http renyongjie668 blog 163 com blog static 160053120
  • 今天面试招了个18K的人,从腾讯出来的果然都有两把刷子···

    公司前段时间缺人 也面了不少测试 前面一开始瞄准的就是中级的水准 也没指望来大牛 提供的薪资在15 20k 面试的人很多 但平均水平很让人失望 看简历很多都是4年工作经验 但面试中 不提测试工具 仅仅基础的技术很多也知之不详 多数人数年的工
  • Android 系统启动流程简介

    1 Init 进程启动流程 2 Zygote启动流程 3 SystemServer启动流程 1 Init 进程启动流程 Android启动流程 init进程 gt Zygote进程 gt SystemServer进程 gt 各种应用进程 I
  • [源码解析] NVIDIA HugeCTR,GPU 版本参数服务器---(7) ---Distributed Hash之前向传播

    Python微信订餐小程序课程视频 https edu csdn net course detail 36074 Python实战量化交易理财系统 https edu csdn net course detail 35475 源码解析 NV
  • 【Php】PhpSpreadsheet安装的坑怎么这么多!

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 人是代码非 一 PhpSpreadsheet不安装直接用行不行 二 安装的坑 1 缺少fileinfo扩展 2 下载中断 3 proc open函数被禁用 4 co
  • Jmeter 集合点详细讲解

    集合点 让所有请求在不满足条件的时候处于等待状态 如 我集合点设置为50 那么不满足50个请求的时候 这些请求都会集合在一起 处于等待状态 当达到50的时候 就一起执行 从而达到并发的效果 那么Jmeter中可以通过同步定时器Synchro
  • Mybatis

    最近又遇到mybatis的问题了 所以把之前写的和补充的笔记一起放上来 一 动态sql 在编写项目的时候经常需要拼接一些复杂的SQL语句 而拼接过程中很容易导致错误 而Mybatis的动态SQL功能正好能够解决这种问题 可以通过使用 if
  • 【长文预警】美团联合创始人王慧文清华产品课

    前言 一 成功和失败的产品 一般来说在一个领域里一款产品的成功对应着无数产品的失败 根据老王个人的经验 成功和失败的比例大约是1 30 失败的原因多种多样 有些啥都没做对 有些作对了一部分 这里列举的失败案例主要讲做对了一部分的 准确说算是
  • sonar.java.binaries的配置

    从sonarQube 4 12开始 sonar将会进行程序的动态检查 不配置sonar java binaries属性将会出错 From SonarJava version 4 12 binary files are required fo
  • 在 Mac 上使用 VMware 安装 Windows 11

    因为项目原因 需要在 windows 环境下测试一下 electron 的表现 于是就记录一下在 mac 虚拟机上安装 windows 的体验 总体来说难度不大 我电脑的情况 2020 款 macbook pro 16g 512g 前期准备
  • golang版本管理gvm

    今天小土带来一篇关于Go版本管理器gvm的小短文 废话不多说 开始安装 安装 如果你使用的mac mac 需要先安装xcode select 没安装过的同学可以按照如下命令进行执行安装 这里不做太多说明了 xcode select inst
  • 地震逃生【最大流模板题】

    题目链接 P1343 地震逃生 简单的最大流的模板 小心 0 的RE情况 读题 另外 写的是ISAP include
  • 微信小程序授权登录页面(有提示窗)

    微信小程序授权登录 有弹窗提示 1 效果显示 1 1 授权登录页面 1 2 授权登录提示弹窗 1 3 拒绝授权登录 1 4 允许登录后 跳转到小程序首页 2 代码 2 1 wxml 文件
  • 日志审计功能实现

    1 前言 日志审计功能就是将用户进行的增加 修改和删除操作内容 操作方法 操作人以及操作时间等统一格式后集中放入数据库存储 这样做是为了提高系统的安全性 方便系统发生事故后的溯源和恢复 2 日志审计实现 2 1 设计数据库 下图为数据库中的
  • react基础06--react综合案例-电商网站导航

    react基础06 react综合案例 电商网站导航 1 介绍 2 案例设计模块 2 1 分类导航数据模型设计 2 2 一级分类导航切换高亮效果 2 3 显示二级分类导航 2 4 路由跳转到二级导航的商品列表 2 5 商品搜索 3 注意事项