前言
react+webpack4搭建前端项目分为三个章节。链接如下。目的是实现从零搭建一个react后台管理系统
1、react+webpack4搭建前端项目(一)基础项目搭建
2、react+webpack4搭建前端项目(二)react全家桶的使用
3、react+webpack4搭建前端项目(三)打包优化
webpack配置的讲解
4、react+webpack4.x搭建前端项目(四)配置抽取和区分环境
5、react+webpack4.x搭建前端项目(五)多页面配置
6、react+webpack4.x多模块打包配置
这是第二章,react全家桶的使用
废话不多说啦。接着上一篇react+webpack4搭建前端项目(一)我们正式进入react全家桶技术篇章,如果对于项目不清楚或者在下面有什么疑惑,建议先看一下上一篇文章熟悉一下项目由来
使用react-router-dom管理路由,这里使用react-router4.x以后的版本,请注意,和3.x的使用还是有很大的区别
npm install -S react-router-dom
我们为什么使用react-router-dom呢?
先简单说下各自的功能:
react-router: 实现了路由的核心功能
react-router-dom: 基于react-router,加入了在浏览器运行环境下的一些功能,例如:Link组件,会渲染一个a标签,BrowserRouter和HashRouter组件。显而易见react-router-dom功能更丰富,所以选择react-router-dom代替react-router
下面接着上一篇文章的项目,我们对项目进行改造:
新建blog,resume,user页面,如下
分别编写blog,resume,user,home(上篇文章已完成)组件
此处删除home/index.less,修改home/index.js内容:
import React from 'react'
export default class HomeIndex extends React.Component {
render(){
return (
<div>
<p>HomeIndex</p>
</div>
)
}
}
blog/index.js
import React from 'react'
export default class BlogIndex extends React.Component {
render(){
return (
<div>
<p>BlogIndex</p>
</div>
)
}
}
resume/index.js
import React from 'react'
export default class ResumeIndex extends React.Component {
render(){
return (
<div>
<p>ResumeIndex</p>
</div>
)
}
}
user/index.js
import React from 'react'
export default class UserIndex extends React.Component {
render(){
return (
<div>
<p>UserIndex</p>
</div>
)
}
}
以上这些组件是最简单的组件
新建src/router.js
import React from "react"
import { Route,BrowserRouter,Link,Switch } from "react-router-dom"
import HomeIndex from "./home"
import BlogIndex from "./blog"
import ResumeIndex from "./resume"
import UserIndex from "./user"
class AppRouter extends React.Component {
render(){
return (
<BrowserRouter>
<ul>
<li><Link to="/home">home</Link></li>
<li><Link to="/blog">blog</Link></li>
<li><Link to="/resume">resume</Link></li>
<li><Link to="/user">user</Link></li>
</ul>
<div>
{/* Switch只显示一个组件。加exact表示精确匹配/。如果不加exact,/xxx也会匹配/。 */}
<Switch>
{/* exact */}
<Route path="/home" component={HomeIndex} />
<Route exact path="/blog" component={BlogIndex}/>
<Route exact path="/resume" component={ResumeIndex}/>
<Route exact path="/user" component={UserIndex}/>
</Switch>
</div>
</BrowserRouter>
)
}
}
export default AppRouter;
这里使用react-router-dom的history模式,简单写了一个导航,点击每个导航,跳转到相应的页面。运行npm run dev,打开http:localhost:8081,效果如图
到此react-router-dom基本使用已经完成。
因为我们这里是配合项目使用,详细的react-router-dom不过多讲解,如果想学习更多基本用法,请查看官方文档。在后边随着项目的复杂,后边我们还会说一下嵌套路由,页面之间的跳转等等使用方法。
最后我们需要清除页面,标签的默认样式。代码可以去网上找一份,网上随处可见。
然后在项目根目录新建static/css/reset.min.css,在index.html模板引入
<link rel="stylesheet" href="/static/css/reset.min.css">
重新运行,你会发现找不到/static/css/reset.min.css。因为这里只是在index.html中引入了文件,但是并没有在webpack中处理静态文件,我们需要把static目录的内容通过webpack插架
编译构建到包里;此处需要用到copy-webpack-plugin
npm install -D copy-webpack-plugin@4.x
在build/webpack.base.config.js`中添加公用的插件plugins,
plugins:[
new CopyWebpackPlugin([
{
from: utils.resolve('../static'), // 从哪个目录copy
to: "static", // copy到那个目录
ignore: ['.*']
}
])
]
重新运行,你会发现默认样式清除了!
使用mobx管理数据
在react中使用mobx,不仅需要使用mobx,还需要结合react的插件,那就是mobx-react。
第一先安装这两个必须包
npm install -S mobx mobx-react
mobx的基本用法请看这里mobx
mobx-react是mobx和react的结合,提供Provider组件统一管理mobx数据;inject为react组件注入某个mobx实例;observer实现mobx实现react组件和mobx数据的双向绑定(和react-redux的connect差不多)等等
创建mobx实例并在react入口文件引入
我们这里在user目录下先建store/UserList.js,创建管理用户列表页面的mobx实例
import { observable,action } from "mobx"
class UserListStore {
@observable name;
constructor(){
this.name = "my name is user list;";
}
}
export default new UserListStore();
面我们在src下新建store/index.js目录,统一管理项目的mobx实例:
import UserListStore from "./../user/store/UserList"
const store = {
UserListStore
}
export default store;
在修改src/index.js,导入文件
import React from 'react'
import ReactDom from 'react-dom'
import { Provider } from "mobx-react"
import AppRouter from "./router"
import store from "./store"
class App extends React.Component {
render(){
return (
<Provider {...store}>
<AppRouter />
</Provider>
)
}
}
ReactDom.render(<App/>,document.getElementById("app"))
重新运行项目,不出所料报错。为什么呢?熟悉mobx的同学应该都知道,mobx的特色是使用装饰器来来修饰mobx实例中属性和方法,以及react-mobx也是通过装饰器来使用。
装饰器可以通过@关键字加上相关的方法。来达到为属性,方法,class添加其它功能的作用。装饰器作用的作用其实用很大,比如java的spring运用最广泛,想学习的同学可以去查相关资料。
我们需要在项目配置对装饰器的支持
装npm install -D @babel/plugin-proposal-decorators,在.babelrc文件的pulgins数组添加
["@babel/plugin-proposal-decorators",{"legacy": true}], // 配置对装饰器的支持
把"@babel/plugin-proposal-class-properties"修改成或者添加@babel/plugin-proposal-class-properties
["@babel/plugin-proposal-class-properties",{"loose":true}] // 支持类属性的插件
注意这项配置一定要在@babel/plugin-proposal-decorators之后,不然还是一样会报错。
react组件中使用mobx
通过inject把需要的mobx实例注入到react组件
使用observer实现组件和数据的双向绑定
在class组件使用@observer修改组件,添加setName方法
参考user/store/userList.js下的setName方法
import { observable,action } from "mobx"
class UserListStore {
@observable name;
constructor(){
this.name = "my name is user list;";
}
@action
async setName(value){
this.name = value;
}
}
export default new UserListStore();
一个修改name示例
import React from 'react'
import {withRouter} from 'react-router-dom'
import { inject, observer } from "mobx-react"
@inject("UserListStore")
@observer
class HomeIndex extends React.Component {
render(){
return (
<div>
<p onClick={()=>{
const {UserListStore} = this.props;
// this.props.history.push({pathname: '/resume'});
UserListStore.setName("ha ha ha")
}}>121456</p>
</div>
)
}
}
export default withRouter(HomeIndex);