博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react全家桶
阅读量:7064 次
发布时间:2019-06-28

本文共 8869 字,大约阅读时间需要 29 分钟。

1、基础介绍

  • 本文采用的模块之家的实例项目为模板,采用react+react-router-dom+redux+axios+antd+js-cookie+less等技术栈来实现。
  • 本文假设你对react已经有基本了解。

2、创建项目

  • create-react-app react_pc_demo
  • cd react_pc_demo
  • npm (run) start

3、暴露配置文件

  • react项目默认是隐藏配置文件的。
  • 本项目选择暴露配置文件的方式
  • npm run eject暴露配置文件(操作的时候本地不能有修改的文件、否则会报错This git repository has untracked files or uncommitted changes)

4、配置别名

  • webpack.config.jsalias配置中增加如下配置
alias: {  '@': paths.appSrc}复制代码
  • 修改引用方式,重启(修改配置文件必须重启才能生效)验证配置是否成功
// import logo from './logo.svg';// import './App.css';import logo from '@/logo.svg';import '@/App.css';复制代码

5、项目结构规划

  • 可以修改成自己熟悉的项目结构
+-- src/                                    ---核心代码目录|   +-- api                                 ---api配置|   +-- assets                              ---静态资源文件夹|   +-- components                          ---功能组件|   +-- layout                              ---布局组件(用于划分页面布局的组件)|   +-- pages                               ---页面组件(具有路由)|   +-- router                              ---路由配置文件|   +-- styles                              ---样式配置文件 |   +-- utils                               ---辅助函数|   --- index.js                            ---项目入口文件复制代码
  • 后续可根据需求进行扩展和模块划分

6、less配置

  • 本文采用less对css进行预处理
npm install -S less less-loader / cnpm i -S less less-loader复制代码
  • webpack.config.jsstyle files regexes配置中增加如下配置
const cssRegex = /\.css|less$/; 修改为=> const cssRegex = /\.css|less$/复制代码
  • webpack.config.jsloaders配置中增加如下配置
{  loader: require.resolve('less-loader')}复制代码
  • 修改css文件为less文件、重启服务查看效果

7、配置路由

  • cnpm i -S react-router-dom // react-router-dom依赖包含react-router
  • 新建路由文件,在router文件下新建index.js文件
import React from "react"import { HashRouter, Route, Switch, Redirect } from "react-router-dom"import Home from '@/pages/home'export default () => (  
)复制代码
  • 在项目入口文件index.js中使用router
import Router from "@/router"ReactDOM.render(
, document.getElementById('root'));复制代码
  • 路由介绍
  1. HashRouter/BrowserRouter 定义路由方式Hash/或者Location
  2. Switch路由切换组件,多个Route时用Switch包裹,否则会报警告
  3. Route路由
  4. Redirect路由重定向
  5. exact路由绝对匹配

8、状态管理(redux)

  • cnpm i -S redux react-redux redux-thunk // redux-thunk => action异步处理
  • 新建store文件夹,新建state,actions,reducers,actionTypes
state: 初始化数据import { getUserInfo } from '@/utils/store'export default {  userReducer: {    userName: getUserInfo()  },  orderReducer: {    orderType: 'order',    completed: 'false',    num: 0  }}复制代码
actionTypes: 集中管理action操作类型export const USER_LOGIN = 'USER_LOGIN'export const ADD_ORDER_NUM = 'ADD_ORDER_NUM'export const USER_LOGOUT = 'USER_LOGOUT'复制代码
actions: 修改state必须通过actionimport { USER_LOGIN, ADD_ORDER_NUM, USER_LOGOUT } from './actionTypes'export function userLogin(payload) {  return {    type: USER_LOGIN,    payload  }}export function logout() {  return {    type: USER_LOGOUT  }}export function addOrderNum() {  return {    type: ADD_ORDER_NUM  }}复制代码
reducers: 数据处理import { combineReducers } from 'redux'import { USER_LOGIN, ADD_ORDER_NUM, USER_LOGOUT } from './actionTypes'import initialState  from './state'import { setUserInfo, removeUserInfo } from '@/utils/store'let userReducer = (state = initialState.userReducer, action) => {  switch (action.type) {    case USER_LOGIN:      setUserInfo(action.payload)      return {        ...state,        userName: action.payload      }    case USER_LOGOUT:      removeUserInfo()      return {        ...state,        userName: null      }    default:      return state  }}let orderReducer = (state = initialState.orderReducer, action) => {  switch (action.type) {    case ADD_ORDER_NUM:      return {        ...state,        num: ++state.num      }    default:      return state  }}export default combineReducers({  userReducer,  orderReducer,})复制代码
  • 在页面中使用
  1. 修改index.js文件
import { createStore, applyMiddleware } from 'redux'import reducers from './reducers'import initialState  from './state'import thunk from "redux-thunk"const enhancer = applyMiddleware(thunk)export default createStore(  reducers,  initialState,  enhancer)复制代码
  1. 高阶组件connect
// 此处仅仅只是演示页面import React, { Component } from 'react';import PropsTypes from 'prop-types' // cnpm i -S prop-typesimport { connect } from 'react-redux' // connect高阶组件import { addOrderNum } from '@/store/actions' // 引入actionclass OrderNum extends Component {  static PropsTypes = { // 定义数据类型    orderType: PropsTypes.string,    num: PropsTypes.number.isRequired,    completed: PropsTypes.bool,    addOrderNum: PropsTypes.func.isRequired  }  render() {    return (      

orderType: {this.props.orderType}

orderNum: {this.props.num}

completed: {this.props.completed}

// 使用action
); }}const mapStateToProps = (state, ownProps) => ({ // 当前组件需要使用的state数据 orderType: state.orderReducer.orderType, completed: state.orderReducer.completed, num: state.orderReducer.num})const mapDispatchToProps = { // 当前组件需要反馈的action addOrderNum}export default connect(mapStateToProps, mapDispatchToProps)(OrderNum)复制代码

9、中间件middleware

  • 安装,上面已安装(可忽略)
cnpm i -S redux-thunk // 增强action异步处理复制代码
  • 使用
// 修改store  import { createStore, applyMiddleware } from 'redux'  import reducers from './reducers'  import initialState  from './state'  import thunk from "redux-thunk"  const enhancer = applyMiddleware(thunk)  export default createStore(    reducers,    initialState,    enhancer  )复制代码

10、添加布局layout和子路由

  • 在layout下则增加DefaultLayout组件,新增公共头部底部组件
  • 在router下增加module文件夹,新增frontRouter组件,在DefaultLayout使用此模块路由。

11、ui(antd)的使用

  • 安装依赖
cnpm i -S antd复制代码
  • 配置, style为css和true区别你是否需要使用babel-plugin-import引入你的样式(在非按需引用时你需要将.css改为.less),它的好处在于可以显著减少包大小
在babel-loader的plugins中增加如下配置['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }]或者['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }]复制代码
  • 重启后使用
import { Button } from 'antd'复制代码
  • ps,当你在使用style: true时可能遇到以下错误,Inline JavaScript is not enabled. Is it set in your options?,解决办法,在less-loaderoptions增加以下配置javascriptEnabled: true
Failed to compile../node_modules/_antd@3.12.1@antd/es/button/style/index.less (./node_modules/_css-loader@1.0.0@css-loader??ref--6-oneOf-3-1!./node_modules/_postcss-loader@3.0.0@postcss-loader/src??postcss!./node_modules/_less-loader@4.1.0@less-loader/dist/cjs.js!./node_modules/_antd@3.12.1@antd/es/button/style/index.less)// https://github.com/ant-design/ant-motion/issues/44.bezierEasingMixin();^Inline JavaScript is not enabled. Is it set in your options?      in D:\user\80002912\桌面\my_project\react_pc_demo\node_modules\_antd@3.12.1@antd\es\style\color\bezierEasing.less (line 110, column 0)复制代码
  • 修改如下配置
code{  loader: require.resolve('less-loader'),  options: {    javascriptEnabled: true  }}复制代码

12、前后端交互

  • 安装依赖(本项目使用的是axios)
cnpm i -S axios qs复制代码
  • 二次封装axios,详见api下index.js和fetch.js文件
api   fetch.js 二次封装axios  index.js 集中管理api,可根据需要进行模块化划分,在组件中按需引用即可复制代码

13、react-router路由跳转

  • 路由组件的跳转
this.props.history.push('/path')复制代码
  • 外部组件的跳转
  1. 使用Link跳转
go to other page复制代码
  1. 路由组件传递
如test为home组件的子组件
在test中this.props.history.push('/path')复制代码
  1. 通过context共享
home组件getChildContext() { // 通过context申明共享数据  return {    history: createHashHistory()  }}static childContextTypes = { // 申明共享数据类型  history: PropTypes.object}在test中static contextTypes = { // 申明需要使用的共享数据及类型  history: PropTypes.object}在'render'中通过'this.context.history'使用复制代码
  1. 直接引用history
import createHashHistory from 'history/createHashHistory'const history = createHashHistory()在组件内部history.push('/path')复制代码

14、组件异步加载(code split)

  • react-router 4.0 以上版本
  1. 借助babel-plugin-syntax-dynamic-import + react-loadable实现按需加载
cnpm i -D babel-plugin-syntax-dynamic-importcnpm i -S react-loadable复制代码
  1. 组件内使用,核心代码如下,将import Home from '@/pages/home'改为使用Loadable()的方式const Home = Loadable({loader: () => import('@/pages/home'), loading})
import Loadable from 'react-loadable'import loading from '@/components/common/loading'  // 自定义的loading组件// import Home from '@/pages/home';// import Login from '@/pages/login';// import Error_404 from '@/pages/error404';// import DefaultLayout from '@/layout/default';const Home = Loadable({loader: () => import('@/pages/home'), loading});const Login = Loadable({loader: () => import('@/pages/login'), loading});const Error_404 = Loadable({loader: () => import('@/pages/error404'), loading});const DefaultLayout = Loadable({loader: () => import('@/layout/default'), loading});复制代码
  • react-router 4.0 以下版本
  1. 借助require.ensure(),如:
const Home = (location, cb) => {    require.ensure([], require => {        cb(null, require('./component/home').default);    }, 'home');}或者借助包装类'Bundle Loader'npm i --save bundle-loaderconst Home = (props) => (    
{ require.ensure([], require => { cb(require('./component/home')); }); }}> {(Home) =>
}
);复制代码
  1. 使用import(),如:
const Home = (props) => (    
import('./component/home')}> {(Home) =>
}
);复制代码

15、总结

  • 本文已模板之家项目为实现,介绍了开发过程中的各种配置。
  • 后期在开发时,可能对代码部分略有修改,但思路不变。
  • 本文的实例已放到马云上,并持续同步更新。
  • 目前已实现的功能有首页、登录页、购物车等

转载地址:http://iyill.baihongyu.com/

你可能感兴趣的文章
MySQL学习四部曲
查看>>
SCCM 2012 R2实战系列之一:SQL安装
查看>>
windows下安装memcached
查看>>
08R2-12R2基于访问权限的文件枚举
查看>>
Gartner:网络信息安全投入依然不在中国政企客户优先投入之列
查看>>
恢复误删除的ESXi服务器存储VMFS卷
查看>>
SFB 项目经验-22-如何查看存储的管理IP地址
查看>>
libevent入门教程:Echo Server based on libevent
查看>>
.NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
查看>>
一次服务器CPU占用率高的定位分析
查看>>
安装office2007 1706错误
查看>>
crontab中执行多条命令
查看>>
25 JavaScript的幻灯片用于在Web布局的精彩案例
查看>>
用C语言写的迅雷看看XV文件提取器及C语言源代码
查看>>
ccpuid:CPUID信息模块 V1.01版,支持GCC(兼容32位或64位的Windows/Linux)
查看>>
用dom4j操作XML文档(收集)
查看>>
WinForm实例源代码下载
查看>>
hdu 1829 A Bug's Life(并查集)
查看>>
每日英语:Chinese Writer Wins Literature Nobel
查看>>
java中三种主流数据库数据库(sqlserver,db2,oracle)的jdbc连接总结
查看>>