React实现简单电商案列(含二级路由跳转,获取JSON数据)

React实现简单电商案列

操作思路:

  1. UI界面怎么实现UI (User Interface)
    (1) 涉及路由跳转Route
    (2) json数据来渲染页面
  2. 功能代码实现:
    (1) 通过素材中API完成数据请求及数据渲染
    (2) 点击左侧一级分类,右边动态筛选对应的二级分类数据(不是配置多个路由实现)
    (3) 完成路由配置首页、分类、购物车、个人,除了分类其它页面内容自定义

需要安装的插件:

  1. cnpm i react-router-dom -S
  2. cnpm i axios -S

操作步骤:

  1. html页面
   <!DOCTYPE html>
<html lang="en"> 
<head>
 <meta charset="utf-8" />
 <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
 //在此处引用了icon font图标
 <link rel="stylesheet" href="//at.alicdn.com/t/font_1691202_lswlgnvrxwl.css">
 <meta name="viewport" content="width=device-width, initial-scale=1" />
 <meta name="description" content="Web site created using create-react-app" />
 <title>React App</title>
</head>
<body>
 <div id="root"></div>
</body>
</html>
  1. 在新建项目中的index.js页面中引入主页面App
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render( <App />,document.getElementById('root'));
  1. 在App页面中引入Main组件文件
import React, { Component } from 'react';
import {BrowserRouter,Route,Link,Switch} from "react-router-dom";
import Main from "./Main";
import GoodsList from "./Main/Classify/GoodsList";
export class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <Switch>
        <Route path="/" component={Main}></Route>
        </Switch>
      </BrowserRouter>
    )
  }
}
export default App
  1. Main文件中包含了底部导航中的路由配置首页、分类、购物车、个人四个页面
import React, { Component } from 'react'
import {Switch,Link,Route} from "react-router-dom";
import Home from "./Home";//首页
import Classify from "./Classify";//分类
import Cart from "./Cart";//购物车
import My from "./My";//我的
import "./index.css";
export class index extends Component {
    constructor(){
        super()
        this.state={
            sel:"",
       		//input框的值
            InputValue:"",
            //一个搜索框的列表 可以实现一个简单的模糊搜索
            list:[
                {
                    "title":"新款女士卫衣",
                },{
                    "title":"新款女士外套",
                },{
                    "title":"2019男士外套",
                },{
                    "title":"新款男士卫衣",
                },{
                    "title":"javascript",
                }
                
            ]
        }
    }
    
    //获取input框里的值
    handelInput(e){
        this.setState({
            InputValue:e.target.value,
        })
    }
    
    render() {
        const {sel} =this.state;
        return (
            <div style={{width:"100%"}}>
            <div className="top">
            <input 
            type="text" 
            placeholder="搜索商品"
            style={{width:"100%", height:"50px",fontSize:"20px"}}
            value={this.state.InputValue}
            onChange={this.handelInput.bind(this)}
            />
            </div>
            
                //模拟得一个搜索框列表
                <div className="searchlist">
            {this.state.list.map((item,index)=>{
                //模拟一个空数组
                 let newlist=[];
                 //如果list列表中的title包含了你要搜索的内容
                 if(item.title.includes(this.state.InputValue)){
                 //就将他们添加到空数组中遍历
                 newlist.push(item)
                     return(
                    <li key={index}>{item.title}</li>
             )
                } 
             })}
            </div>
                  
            <div className="content">
            <Switch>
            <Route path="/home" component={Home}></Route>
            <Route path="/my" component={My}></Route>
            <Route path="/cart" component={Cart}></Route>
            <Route path="/" component={Classify}></Route>
            </Switch>
            </div>

             <div className="footer">
             <Link to="/home">
             //sel为类名 这里运用了三目运算 如果点击 sel==sy 的话就为sel中的样式 否则为nosel中的样式 
             <div className={sel == "sy" ? "sel" : "nosel"} onClick={()=>{
                 this.setState({sel:"sy"})
             }}>		
             //这里引用了icon font中的图标 在HTML页面中以link方式引用
             <span className="iconfont icon-shouye1 icona" ></span>
             <div>首页</div>
             </div>
             </Link>
             <Link to="/">
             <div className={sel == "fl" ? "sel" : "nosel"} onClick={()=>{
                 this.setState({sel:"fl"})
             }}>
             <span className="iconfont icon-leimupinleifenleileibie icona"></span>
             <div>分类</div>
             </div>
             </Link>
             <Link to="/cart">
             <div className={sel == "gwc" ? "sel" : "nosel"} onClick={()=>{
                 this.setState({sel:"gwc"})
             }}>
             <span className="iconfont icon-gouwuche icona"></span>
             <div>购物车</div>
             </div>
             </Link>
             <Link to="/my">
             <div className={sel == "wd" ? "sel" : "nosel"} onClick={()=>{
                 this.setState({sel:"wd"})
             }}>
             <span className="iconfont icon-ren icona"></span>
             <div>我的</div>
             </div>
             </Link>
             </div>   
            </div>
        )
    }
}
export default index

  1. Main页面的样式
*{
    padding: 0;
    margin: 0;
    list-style: none;
}
.top{
    width:100%;
    height:50px;
    position: fixed;
    top:0;
    z-index: 1000;
    border:1px solid grey;
    box-sizing: border-box;
}
.footer{
    width:100%;
    height:60px;
    border:1px solid grey;
    box-sizing: border-box;
    position: fixed;
    bottom:0;
    display: flex;
    justify-content:space-around;
    align-items: center;
    flex-wrap: none;
    z-index: 1000;
    font-size: 16px;
}
a{
    text-decoration: none;
}
.footer .sel{
    color:red;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.footer .nosel{
    color:grey;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.icona{
    font-size: 22px;
}
.searchlist{
    margin-top:50px;
    border:1px solid grey;
}
  1. 首页页面
import React, { Component } from 'react'

export class index extends Component {
    render() {
        return (
            <div>
              首页  
            </div>
        )
    }
}

export default index

7.分类页面

import React, { Component } from 'react';
import axios from "axios";
import "./style.css";
export class index extends Component {

    constructor() {
        super();
        this.state = {
            // 全部数据
            allList: [],
            // 一级导航数据
            oneNav: [{
                dateAdd: "",
                icon: "",
                id: 0,
                isUse: true,
                key: "0",
                level: 0,
                name: "",
                paixu: 0,
                pid: 0,
                type: "",
                userId: 0
            }],
            // 二级导航数据
            twoNav: [{
                dateAdd: "",
                icon: "",
                id: 0,
                isUse: true,
                key: "0",
                level: 0,
                name: "",
                paixu: 0,
                pid: 0,
                type: "",
                userId: 0
            }],
            // 默认选中项
            defaultSelected: 0
        }
    }

    componentDidMount() {
        axios.get("https://api.it120.cc/small4/shop/goods/category/all")
            .then((ret) => {
                if (ret.data.msg == 'success') {
                    //  先获取JSON(列表中的全部数据)的全部数据
                    let classifyList = ret.data.data;
                    // 模拟一级列表数据
                    let tempNavOne = [];
                    // 模拟一级列表数据
                    let tempNavTwo = [];
                    // 获取一级列表的id
                    let tempId = 0;
                    // 从整个数据中遍历一级列表
                    classifyList.map((item) => {
                        if (item.level == 1) {//查询一级分类可以通过pid 也可以通过leve
                            tempNavOne.push(item)//然后将一级列表的内容添加到 模拟的一级类表数据中
                        }
                        if (item.paixu == 0 && item.level == 1) {
                            // 默认选中一级列表项 先获取默认选项中的ID
                            tempId = item.id;
                        }
                    })
                    // 从整个数据中遍历二级列表
                    classifyList.map((item) => {
                        if (item.pid == tempId) {
                            tempNavTwo.push(item);
                        };
                    });

                    // 重新设置状态
                    this.setState({
                        allList: classifyList,
                        oneNav: tempNavOne,
                        twoNav: tempNavTwo,
                        defaultSelected: tempId
                    });
                };
            });
    }

    render() {
        // const {oneNav,twoNav,defaultSelected,allList} =this.state
        return (
            <div className="classify_content">
                <div className="classify_left">
                    {this.state.oneNav.map((item, index) => {
                        return (
                            <div key={index}
                                className="navstyle"
                                style={{
                   // 设置字体颜色 如果当前默认选中项==当前id 的话字体颜色为红色 否则为灰色
                                color: this.state.defaultSelected == item.id ? "red" : "grey"
                                }}
                                onClick={this.handelNavone.bind(this,item.id)}
                            >{item.name}
                            </div>
                        )
                    })}
                </div>
                <div className="classify_right">
                    {this.state.twoNav.map((item,index)=>{
                        return(
                            <div 
                            key={index}
                            className="classify_right_list"
                            ><img src={item.icon} alt=""/>{item.name}</div>
                        )
                    })}
                </div>
            </div>
        )
    }

    handelNavone(id){
        //防止报错 从新获取一下json数据
        let classifyList=this.state.allList;
        // 点击一级列表的时候出现二级列表
        // 模拟二级列表数据
        let tempNavTwo = [];
        //重新渲染二级列表的数据
        classifyList.map((item)=>{
        // 如果二级列表的Pid==当前列表的id时将数据添加到二级列表中
            if(item.pid==id){
                tempNavTwo.push(item);  
        }
        });
        
        this.setState({
            defaultSelected:id,
            twoNav:tempNavTwo,
        })
    }


}

export default index
  1. 分类页面中的css样式
.classify_content{
    width:100%;
    margin-top:90px;
    border:1px solid grey;
    box-sizing: border-box;
}
.classify_content .classify_left{
    width:20%;
    height:400px;
    display: flex;
    align-items: center;
    flex-direction: column;
    flex-wrap: nowrap;
    border:1px solid grey;
    box-sizing: border-box;
}
.navstyle{
    width:100%;
    display: flex;
    height:50px;
    justify-content: center;
    align-items: center;
    border:1px solid grey;
}
.classify_right{
    height:400px;
    position: absolute;
    top:250px;
    right:0px;
    width:79%;
    display: flex;
    align-items: center;
    flex-direction: row;
    flex-wrap: wrap;
    box-sizing: border-box;
}
img{
    width:100%;
    height:90px;
    align-items: center;
}
.classify_right_list{
    box-sizing: border-box;
    width:108px;
    height:100px;
    text-align: center;
}

  1. 购物车页面
import React, { Component } from 'react'

export class index extends Component {
    render() {
        return (
            <div>
                购物车页面
            </div>
        )
    }
}

export default index
  1. 我的页面
import React, { Component } from 'react'

export class index extends Component {
    render() {
        return (
            <div>
               我的页面
            </div>
        )
    }
}

export default index

接近尾声了 以上仅代表个人想法 下期再见喽。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值