react 创建项目 sass router redux
创建项目第一步 基本搭建
在创建之前,需要有一个git 仓库,我们要把项目搭建到git 中
目录介绍
cd 到某个盘
mkdir workspace 创建workspace文件夹
cd workspace 进入workspace文件夹
workspace一般为我们仓库和项目总目录
git@1 仓库一(前端自己项目,如果自己是前端leader)
www.bdplus.cn 为上线文件夹
pc或w 为 pc 电脑端项目
h5或m 为h5 网页或app 中网页或公众号
minstore 小程序(如果分微信和支付宝可wminstore tminstore)
app 前端app 用户开发
mkdown (一些备注文件)
以下为正常开发项目,以上为对应上线打包后文件
w
h5
minstore
app
mkdown
如果有其他方式可自己组织
git@2 仓库二 (其他项目比如后端等)
git@3 仓库三
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
Cmd
Copy
查看node 版本
node -v
或
使用nvm 进行node 版本安装与切换
1、node 版本
nvm use v14
Now using node v14.15.3 (npm v6.14.9)
node -v
v14.15.3
为了保证同步,选择node 版本14
2、开始创建项目
npx create-react-app my-app
官方标准命令,my-app 为项目名称
npx create-react-app scss-route-mobx
....
3、git仓库提交
这块你要进行git 提交 主要在企业做项目就应该放到仓库中,如果企业没有,那自己也要弄个仓库,哪天在家改个东西,或像今年的疫情在家办公所以,只要远程仓库有代码,电脑就是另一个事了。
4、cd scss-route-mobx 进入项目目录
先进入到这个项目目录
5、yarn eject 开启配置文件
这时候先不着急启项目,先把配置文件开启就是webpack 这些基础配置开启
6、yarn start 启动项目
这时候你再起项目。 算是勉强创建了一个项目
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
Cmd
Copy
创建项目第二步 sass安装
1、sass 安装
yarn add node-sass-chokidar
yarn add npm-run-all
2、修改package.json
"scripts": {
"build-css": "node-sass-chokidar src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive --use-polling --polling-interval 1000",
"start-js": "node scripts/start.js",
"start": "npm-run-all -p watch-css start-js",
"build-js": "node scripts/build.js",
"build": "npm-run-all build-css build-js",
"test": "node scripts/test.js --env=jsdom"
},
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
Cmd
Copy
创建项目第三步 yarn build 打包注意事项
新建一个.env文件与package.json 同在根目录下
GENERATE_SOURCEMAP=false
以下三种路径
PUBLIC_URL=https://www.a.com/
PUBLIC_URL=./
PUBLIC_URL=/
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
JSON
Copy
启动成功并编译成功表示react项目创建成功
至此 一个基本的react 项目算是创建成功了
创建项目第四步 设置代理、nginx 路由配置、跨域处理
src/setupProxy.js 创建文件
yarn add http-proxy-middleware axios
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/home',createProxyMiddleware({
target: 'https://#####.com/',
changeOrigin: true,
})
);
app.use(
'/wp-json',createProxyMiddleware({
target: 'https://#####.cn/',
changeOrigin: true,
})
);
};
以下是具体某个页面中使用
obj = {
mediareports:{
page_number:'2',
page_size:'10'
}
}
const cfg = this.state.mediareports;
this.getApi('/home/mediareports',cfg,{}).then((res)=>{
console.log(res.data)
})
this.getApi('/wp-json/wp/v2/posts',{},{}).then((res)=>{
console.log(res.data)
})
async getApi(url,cfg,headers){
let data = await axios.get(url,{params:cfg},
{
headers: headers
})
return data;
}
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
React JSX
Copy
创建项目第五步 react react-router 路由
react 的文件目录是怎么样
1、pubilc
- index.html
- favicon.ico
- manifest.json
移动App的配置文件,用于指定应用的显示名称、图标、入口页面等信息.
2、src
- components
- alert
index.jsx
- footer
index.jsx
- nav
index.jsx
比如:
导航、弹出层、loading加载动画、分页器等
- images
凡事页面中<img src>标签使用的图片
- js
页面中编写的js功能及开发文件
- store
mobx
context
- styles
img/
css、less、scss
- unit
js一些组件
比如,
如果不用jq,自己封装一些js 的方法
如果手机端有活动页面都需要下载app,同的app 的判断
如果有弹出去js等
- view
home
index.jsx
about
index.jsx
joined
index.jsx
list.jsx
other.jsx
- other
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
HTML
Copy
1、导入包
yarn add react-router-dom;
PS:
react-router 和 react-router-dom
react-router: 实现了路由的核心功能。
react-router-dom: 基于react-router,加入了在浏览器运行环境下的一些功能。
react-router-dom 是 react-router 的加强版呗
因为 React Native 也要路由系统呀。所以还有一个库叫 react-router-native,这个库也是基于 react-router 的,它类似 react-router-dom,加入了 React Native 运行环境下的一些功能。
react-router-dom
react-router-native
React BrowserRouter和HashRouter的区别
BrowserRouter:h5路由(history API)
HashRouter:哈希路由
主要区别
BrowserRouter 和 HashRouter 都可以实现前端路由的功能
BrowserRouter 实现的是单页面的路由切换
HashRouter 实现的是全局路由切换
从原理上
HashRouter在路径中包含了#,相当于HTML的锚点定位。(# 符号的英文叫hash,所以叫HashRouter,和散列没关系哦))
而BrowserRouter使用的是HTML5的新特性History,没有HashRouter(锚点定位)那样通用,低版本浏览器可能不支持。
从用法上
BrowserRouter进行组件跳转时可以传递任意参数实现组件间的通信,而HashRouter不能(除非手动拼接URL字符串),因此一般配合Redux或mobx使用,实现组件间的数据通信。
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
Cmd
Copy
2、新增加Router.js文件
import React from 'react';
import { BrowserRouter, HashRouter, Route, Link, Switch } from 'react-router-dom';
import App from './App.js';
const Router = () => (
<BrowserRouter>
<App/>
</BrowserRouter>
)
export default Router;
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
JavaScript
Copy
3、修改index.js
原App 换成
import Router from './Router';
<Router />
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
JavaScript
Copy
4、App.js(需增加代码分割)
import React , { Component, Suspense, lazy } from 'react';
import { withRouter,NavLink,Switch,Redirect,Route} from 'react-router-dom';
const Home = lazy(() => import('./views/Home'));
import Input from './view/input';
import Event from './view/event';
class App extends Component {
render(){
return (
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/input" component={Input} />
<Route path="/event" component={Event} />
</Switch>
</Suspense>
);
}
}
export default App;
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
JavaScript
Copy
5、新增页面
./view/home/index.jsx
./view/input/index.jsx
./view/event/index.jsx
内容自定义
import { withRouter,NavLink,Switch,Redirect,Route} from 'react-router-dom';
<NavLink to="/">首页</NavLink>
<NavLink to="/input">表单</NavLink>
<NavLink to="/event">事件</NavLink>
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
React JSX
Copy
import React , { Component } from 'react';
import { withRouter,NavLink,Switch,Redirect,Route} from 'react-router-dom';
class View extends Component {
render(){
return (
<React.Fragment>
<div className="mian">这是首页面</div>
<NavLink to="/">首页</NavLink><br/>
<NavLink to="/input">表单</NavLink><br/>
<NavLink to="/event">事件</NavLink>
</React.Fragment>
)
}
}
export default View;
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
React JSX
Copy
创建项目第六步 Redux
1、安装yarn add react-redux redux
2、router store 注入
import {Provider} from 'react-redux';
<Provider stores={store}>
<App/>
</Provider>
完整代码
import React from 'react';
import { BrowserRouter, HashRouter} from 'react-router-dom';
import App from './App.js';
import {Provider} from 'react-redux';
import Store from './store/store.js';
const Router = () => (
<BrowserRouter>
<Provider store={Store}>
<App/>
</Provider>
</BrowserRouter>
)
export default Router;
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
React JSX
Copy
3、创建整个项目 store.js
src/store/store.js
import {createStore, combineReducers} from 'redux';
import {reducer as addReducer} from './views/action/_index.js';
const reducer = combineReducers({
add:addReducer,
// remove:removeReducer,
// edit:editReducer,
})
export default createStore(reducer);
----
我需要创建 Store.js
引入 多个 reducer (store数据片段)
combineReducers 合并整合多个reducer
再进行 createStore()
第一参数 reducer (纯函数,返回新的state)
第二个参数 state 初始化值 null
第三个 中间件
到这个位置
router 基本不需要再修改了
store 只需引入 所需 view下的页面中的reducer
createStore
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
React JSX
Copy
第四步
关于每个view 页面
views
home
每个页面都需要一个state
state 如何生成 Reducer(返回新的state)
action
对象 return{}
type 每个action 名称
ActionTypes
reducer
根据具体的action 名称(type对应)
来编写或计算返回新的state
[...new,..state]
Object.assign()
以上是具体当前view 页面内部以外的redux
jsx
about
每个页面都需要一个state
news
每个页面都需要一个state
usercenter
每个页面都需要一个state
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)
React JSX
Copy
第五步
如何与页面交互
导入
import {connect} from ‘react-redux’;
导出
export default connect(mapStateToProps,mapDispatchToProps)(View);
function mapStateToProps(state) {
return {
isList:state.add
}
}
state.add
add 是哪来的 就是我们Store.js
自定义的reducer
const reducer = combineReducers({
add:addReducer,
// remove:removeReducer,
// edit:editReducer,
})
isList
当前组件 this.props 可以接受到
const {onAddFn,isList,onRemoveFn} = this.props;
轻松的拿到对应 reducer 返回的 State
怎么操作 action
//是一个函数,会得到dispatch和ownProps(容器组件的props对象)两个参数。
const mapDispatchToProps = (dispatch, ownProps) => {
// const {id} = ownProps;
return {
onAddFn: () => dispatch(AddTodo(‘add’))
}
};
onAddFn: () => dispatch(AddTodo(‘add’))
dispatch 操作action
onAddFn 通过this.props 来使用
onClick = {onAddFn}
onAddFn 为自定义 在当前view 页面使用
![点击并拖拽以移动](https://img2020.cnblogs.com/blog/2440839/202106/2440839-20210628201144617-748273675.gif)