项目运行

    1.git clone https://github.com/soybeanxiaobi/React_demo_onlineShop
2.cd React_demo_onlineShop(文件目录)
3.npm install(安装依赖)
4.npm start(项目启动)

功能一览

1.购买产品
2.查看购买的产品
3.删除购买的产品
功能gif图:

实现过程


一、创建项目(脚手架方式)

通过使用create-react-app创建项目,可以免去安装和配置webpack和babel等工具,使得创建项目变得便捷许多,因为他们已经被预先安装和配置了。

npm install -g create-react-app //安装React脚手架

好了,开始构建项目!

    create-react-app react-demo-shop //最后面的是项目文件夹名字
cd react-demo-shop //进入文件夹
npm start //启动

简单解释一下自动生成的各文件的含义

react-demo-shop/
node_modules/ //依赖包
public/
index.html //页面模板
favicon.ico //react的ICON图标
src/ //开发源码
App.css
App.js
App.test.js
index.css
index.js //js入口文件
logo.svg
package.json //定义了这个项目所需要的各种模块,以及项目的配置信息
README.md //备注

二、分析公共组件和路由组件

公共组件总共有两个,一个是顶部的React_Demo:小商城(topInfo);另一个是左侧的导航栏(leftNavigator)

现在对页面结构进行一些更改:

  1. 删除自动生成的App文件,同时删除index.js里App的内容。
  2. 新增images、pages、router文件夹
  3. images用于放置后面需要用到的两张图片:icebox.png、tv.jpg
  4. router用来实现代码的路由功能
  5. pages用来放公共组件(common)和路由组件

现在页面结构如下:

react-demo-shop/
node_modules/
public/
src/ //开发源码
images/ //图片
tv.jpg
pages/
common/ //公共组件
topInfo.js //顶部组件
leftNavigator.js //左侧导航栏
Product.css //产品界面样式
modules/ //路由组件
allProducts/ //所有产品
myProducts/ //我的产品
router/
index.js
index.css //公共css
index.js //js入口文件
package.json
README.md

三、给页面添加公共组件

//topInfo.js
import React,{Component} from 'react' //添加react模块
export default class TopInfo extends Component{
render(){
return(
<div>
<p>React组件Demo:小商城</p>
</div>
)
}
}
//navleftNavigator.js
import React from 'react'
import { Link,withRouter } from 'react-router-dom' class Nav extends React.Component{
render(){
// console.log(this.props.history.location.pathname);
return(
<ul className="nav nav-pills">
<li className={this.props.history.location.pathname === '/' ? 'active' : ''} role="presentation"> //role="presentation"是无障碍阅读
<Link className="liBtn" to='/'>所有产品</Link>
</li>
<li className={this.props.history.location.pathname === '/myProducts' ? 'active' : ''} role="presentation">
<Link className="liBtn" to='/myProducts'>我的产品</Link>
</li>
</ul>
)
} }
//通过withRouter给Nav组件注入路由信息
Nav = withRouter(Nav);
export default Nav;

leftNavigator需要安装react-router-dom模块. 在文件根目录(package.json所在位置)终端输入:

npm install react-router-dom --save

withRouter可以包装任何自定义组件,将react-router 的 history,location,match 三个对象传入。

例如:

//withRouter例子:
render() {
const { match, location, history } = this.props
return (
<div>当前路由:{location.pathname}</div>
)
}

通过对this.props.history.location.pathname进行三元运算,可以高亮当前选中的li

如果仅仅是想在Link上实现点击后呈现高亮效果,可以使用官方文档的activeClassName

http://react-guide.github.io/react-router-cn/docs/API.html#link

最后我们在route/index.js里面加入这两个公共组件!

//route/index.js
import React from 'react'
import { BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.min.css' //添加组件
//公共组件
import Navigator from '../pages/common/leftNavigator' //左侧导航栏组件
import TopInfo from '../pages/common/topInfo' //顶部信息栏 class RouteJs extends React.Component{
render(){
return(
<Router>
<div className="componentWried">
<div className="topInfo">
<TopInfo />
</div> <div className="container-fluid">
<div className="row">
<div className="col-sm-2 left_nav">
<Navigator />
</div>
<div className="col-sm-10 right_cont">
<div className="showComp"> </div>
</div>
</div>
</div>
</div>
</Router>
)
}
} export default RouteJs

因为index.js用到了bootstrap,所以我们还需要去安装bs的依赖包

npm install bootstrap —save

引入css比较容易,不需要依赖其他

import ‘bootstrap/dist/css/bootstrap.css’

引入bootstrap.js 需要先引入jq和popper(编译bs4.0)

npm install jquery —save
npm install popper.js —save //不能漏掉.js,popper和popper.js不一样

如果不安装popper,会提示can’t resolve ‘popper.js’

最后在js入口文件引入路由文件,渲染组件

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import './index.css'; //导入路由Js
import RouterJs from './router/index' ReactDOM.render(<RouterJs />,document.getElementById('root'))//渲染到html标签 registerServiceWorker();//用于在生产环境中为用户在本地创建一个service worker 来缓存资源到本地,用来处理离线缓存、消息推送、后台自动更新等任务,提升应用的访问速度

好,写到这我们看一下现在页面效果

四、给页面添加路由组件

*当路由路径为'/'时候,渲染allProducts组件

*当路由路径为'/myProducts'时候,渲染myProducts组件

//allProducts.js
import React from 'react' class AllProducts extends React.Component{
render(){
return(
<div>
<p>AllProducts</p>
</div>
)
}
}
export default AllProducts; //myProducts.js
import React from 'react' class MyProducts extends React.Component{
render(){
return(
<div>
<p>MyProducts</p>
</div>
)
}
}
export default MyProducts;

我们在index.js中导入这两个路由组件,并添加上相应的路由

import React from 'react'
import { BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.min.css' //添加组件
//公共组件
import Navigator from '../pages/common/leftNavigator' //左侧导航栏组件
import TopInfo from '../pages/common/topInfo' //顶部信息栏 import allProducts from '../pages/modules/allProducts/index' //主页组件
//注意,这里通过component加载组件,首字母是可以小写的,如果是自定义组件,首字母必须大写
import myProducts from '../pages/modules/myProducts/index' //添加信息组件 class RouteJs extends React.Component{
render(){
return(
<Router>
<div className="componentWried">
<div className="topInfo">
<TopInfo />
</div> <div className="container-fluid">
<div className="row">
<div className="col-sm-2 left_nav">
<Navigator />
</div>
<div className="col-sm-10 right_cont">
<div className="showComp">
<Switch>
<Route exact path="/" component={allProducts} /> <Route path="/myProducts" component={myProducts} />
</Switch>
</div>
</div>
</div>
</div>
</div>
</Router>
)
}
} export default RouteJs

注意:exact是匹配精准路径,只有当路径为'/'才会渲染allProducts组件.如果没有exact,当路由路径为'/myProducts',route会先识别到'/',从而先渲染allProducts组件,后再渲染myProducts

我们现在再看一下页面效果:

好,页面总的框架我们已经搭建好啦。

我们现在完善一下路由组件的内容:

首先我们先看一下'所有产品'模块的文件目录:

  allProducts/
index.js //allProductsf根(父)组件
child/ //根据情况划分的公共组件
allProduct.js //公共组件的根组件,实现react-redux
allProductJson.js //这是模拟的产品的数据
allProductLists.js //这里是处理产品添加功能的逻辑组件
modal.css //样式 myProducts/
index.js //allProductsf根(父)组件
child/ //根据情况划分的公共组件
myProdutLists.js //显示我的产品、处理逻辑的组件

介绍一下各个js的内容

//allProductJson.js
//模拟json数据,导入组件中引用
module.exports = {
products:[
{
name:'小米小电视',
description:'优质、优惠、优美',
price:'550',
},
]
} //allProducts.js
//这里用来发送react-redux的action和数据,避免代码过于繁杂,把其他逻辑功能放到子组件实现
import React from 'react'
//导入子组件
import ProductLists from './allProductLists' class AllProducts extends React.Component{
render(){
// console.log(AllProductsJson);
addProduct(e){
//获得子组件传递的数据
console.log(e)
//数据传入函数
// this.props.onSubmitData(e);
}
return(
<div className="allProducts">
<ProductLists onSubmitData={this.addProduct.bind(this)} />
</div>
)
}
}
export default AllProducts;

allProductLists通过props方法传递产品数据给父组件allProduct

//数据传回父级
onSubmitChild(e){
// let idx = e.target.getAttribute('data-idx');
//state存储的数据是在打开模态框的时候添加的
let idx_pro_name = this.state.idx_pro_info.name;
let idx_pro_price = this.state.pro_price;
let idx_pro_count = this.state.pro_count;
//数据传回父级
this.props.onSubmitData({
pro_name:idx_pro_name,
pro_price:idx_pro_price,
pro_count:idx_pro_count,
})
} <button type="button" className="btn btn-primary" onClick={this.onSubmitChild.bind(this)} >添加</button>

父组件获得子组件传递的数据

至此!案例只剩下allProducts和myProducts之间的通信功能.

我们要把在allProducts选中的产品添加到myProducts,但是this.props无法做到没有任何联系的两个组件之间的通信.这时候我们可以使用react-redux。

仅仅使用react-redux的固定模板并不会太难,要深入理解每一个概念,需要花一点功夫。我们可以先预习一下,在下篇再介绍这个案例如何通过react-redux实现两个组件的通信

可以先看看阮一峰老师的文章:http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux.html

React入门实例:组件化+react-redux实现网上商城(1)的更多相关文章

  1. React Native 之 组件化开发

    前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...

  2. React 入门实例

    React 入门实例教程 一.安装 React 的安装包,可以到官网下载. $ git clone git@github.com:ruanyf/react-demos.git 如果你没安装 git, ...

  3. let import export React入门实例教程 connect provider combineReducers 箭头函数 30分钟掌握ES6/ES2015核心内容 Rest babel

    let与var的区别 http://www.cnblogs.com/snandy/archive/2015/05/10/4485832.html es6 导入导出 http://www.csdn.ne ...

  4. React 入门实例教程(转载)

    本人转载自: React 入门实例教程

  5. Vue 入门之组件化开发

    Vue 入门之组件化开发 组件其实就是一个拥有样式.动画.js 逻辑.HTML 结构的综合块.前端组件化确实让大的前端团队更高效的开发前端项目.而作为前端比较流行的框架之一,Vue 的组件和也做的非常 ...

  6. React 入门实例教程【转】

    Any day will do. 哪一天都行 Are you kidding? 你在开玩笑吧! Congratulations! 祝贺你! I don’t mean it. 我不是故意的. 原文作者: ...

  7. 从DOM操作看Vue&React的前端组件化,顺带补齐React的demo

    前言 接上文:谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo 上次写完博客后,有朋友反应第一内容有点深,看着迷迷糊糊:第二是感觉没什么使用场景,太过业务化,还不如直接写Vue ...

  8. React 入门实例教程

    现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Face ...

  9. 2015年最热门前端框架React 入门实例教程

    现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Face ...

随机推荐

  1. python smtplib 发送邮件简单介绍

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式python的smtplib提供了一种很 ...

  2. Hadoop学习笔记之一:Hadoop IPC

    因为某些原因需要把前一段时间对Hadoop(版本基于0.20.2)的学习积累搬到这里,成为一个系列.写得会很简单,只为必要时给自己提醒. IPC框架 所有Hadoop协议接口的实现都依赖Hadoop ...

  3. js 简易时钟

    html部分 <div id="clock"> </div> css部分 #clock{ width:600px ; text-align: center; ...

  4. Linux 安装 mysql 数据库

    1. 克隆虚拟机 2. 上传安装文件 1.上传文件 2.解压文件 tar -xvf 文件 3. 安装数据库 安装顺序: .debuginfo .shared .client .server 1. rp ...

  5. 在Eclipse中创建Dynamic Web Project具有和MyEclipse中Web Project一样的目录结构

    1.在Eclipse中新建Dynamic Web Project 1.1.修改default output folder build\classes修改为:WebRoot\WEB-INF\classe ...

  6. pat 团体赛练习题集 L2-008. 最长对称子串

    对给定的字符串,本题要求你输出最长对称子串的长度.例如,给定"Is PAT&TAP symmetric?",最长对称子串为"s PAT&TAP s&quo ...

  7. php 获取淘宝搜索词 内容

    $s = file_get_contents('http://suggest.taobao.com/sug?extras=1&code=utf-8&callback=g_ks_sugg ...

  8. django模板继承

    可以将每个html公共的部分做成一个基本模板,其他模板继承这个基本模板,则会拥有基本模板的所有内容. views.py from django.shortcuts import render def ...

  9. django模板-if标签和for标签

    在django中,标签写在{%  标签  %}中 if else标签 ①通过if进行条件判断 views.py from django.shortcuts import render def inde ...

  10. Spring RestController 请求参数详解

    Spring RestController 请求参数详解 引用作者jpfss 在阅读之前,最好先了解http请求的get,post,以及各种head头类型,请求参数类型. 无参数,设置RestCont ...