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

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’

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昕光xg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值