React入门实例:组件化+react-redux实现网上商城(1)
2018-08-08 09:57
1136 查看
项目运行
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)
现在对页面结构进行一些更改:
删除自动生成的App文件,同时删除index.js里App的内容。
新增images、pages、router文件夹
images用于放置后面需要用到的两张图片:icebox.png、tv.jpg
router用来实现代码的路由功能
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
😭码字不易,喜欢的可以点一个star,谢谢!
github:https://github.com/soybeanxiaobi/React_demo_onlineShop
相关文章推荐
- React 入门实例教程(原作者: 阮一峰)
- 【SSH网上商城项目实战12】添加和更新商品功能的实现
- 2015年最热门前端框架React 入门实例教程
- React 入门实例教程
- Android基础入门教程——5.2.3 Fragment实例精讲——底部导航栏的实现(方法3)
- React 入门实例
- React 入门实例教程
- Android入门实例四 设置日期和时间的设计与实现
- SSH网上商城项目实战 过滤器实现购物车购物登陆功能的判断。
- React 入门实例教程
- javaWeb入门<1>Servlet+Jsp+JavaBean实现MVC开发模式登陆注册实例详解
- React 入门实例教程
- React 入门实例教程(原作者: 阮一峰)
- 【SSH网上商城项目实战13】Struts2实现文件上传功能
- FLEX入门实例--------FLEX全屏功能实现及右键菜单
- 基于MVC JavaEE,陈铖网上商城项目展示与实现三
- 【SSH网上商城项目实战04】EasyUI菜单的实现
- Spring mvc整合mybatis基于mysql数据库实现用户增删改查及其分页显示的完整入门实例【转】
- React 入门实例教程
- 【SSH网上商城项目实战09】添加和更新商品类别功能的实现