----------------------1.React 环境搭建
npm install react-create-app -g //全局安装脚手架
create-react-app filename // 创建项目并安装依赖
ls 显示当前目录的结构
README.md 看我文档(介绍)
node_modules 安装的第三方依赖包
package.json 表示项目依赖
src 源代码目录(App.css index.js入口js文件)
public 呈现目录 index.html首页
npm start 启动项目(打开3000端口)
npm install redux --save //安装redux
npm install eject 弹出配置文件,可以自定义配置webpack
---------------------2.Express + mongoDB 搭建后台接口
Express 基于node.js 快速极简web开发框架
npm install express --save //安装express
在项目根目录创建一个server 文件夹 ,放置我们后台文件
在server创建一个server.js 文件
const express = require('express') //引入express模块
const app = express(); //新建app
app.listen(9999,function(){ //监听9999端口
监听完成回调函数
})
app.get('/',function(req,res){ //app.get app.post分别开发get和post接口
res.send('hello world'); //res.send()向客户端发送数据 res.json向客户端发送JSON
})
app.get('/data',function(req,res){
//查找数据
User.find({},function(err,doc){
res.json(doc);
})
});
到命令行下执行node server.js 启动node服务器
在浏览器输入 localhost:9999接收到一个hello world
每次修改Nodejs必须保存后断开服务器重新启动 (用nodemon解决)
npm install -g nodemon //安装nodemon可以帮助我们自动更新nodejs服务器
nodemon server.js //改用nodemon 而不是node 去运行server.js
---------------------------------------------3. mongoDB
去mongoDB 官网下载 www.mongoDB.com 安装
Node + mongoDB配合 安装mongoose
npm install mongoose --save //安装mongoose 库依赖
//在server.js 引入mongoose
const mongoose = require('mongoose') //引入mongoose库
//链接
const url = 'mongodb://localhost:27017' //mongoDB默认端口27017
mongoose.connect(url);
mongoose.connection.on('connected',function(){
console.log('mongo connect success'); //这个函数监听是否链接成功数据库
})
//通过mongoose 操作 mongoDB数据库 (存储是JSON)
//类似于mysql的建表 ,新建模型
const User = mongoose.model('user',new mongoose.Schema({
uname: {type:string,require:true}
age: {type:num,require:true}
}))
User.create({ //往模型插入新数据
uname:'kim',
age:18
},function(err,doc){
if(!err){ console.log(doc); }
})
User.find({里面类似于mysql的where},function(err,doc){ //在模型里查找数据
//空对象表示查找所有
})
User.findone({里面类似于mysql的where},function(err,doc){ //在模型里查找一条数据
//第一个参数如果是空对象表示查找所有
})
User.remove({age:18},function(err,doc){ //删除模型age=18的数据
})
User.update({ uname:'kim'},{ '$set':{age:26},function(err.doc) }) //更新uname=kim的age为26
---------------------------------------4.React 基础语法
import React from 'react' //引入React
class App extends React.Component{ //定义一个组件继承React.Component
constructor (props){ //定义构造函数 初始化状态
super(props)
this.state = {
solders:['a ','b','c']
}
}
render(){
return <h1>hello {this.props.world} </h1>
}
}
function com(){
return <h1>函数式声明组件<h1/>
}
//修改状态this.setState()
add(){
this.setState({ solders:[...this.state.solders,'d']}); //解构 并传入
}
<button onClick = {this.add}></button> //这里面add函数的this 不是指向组件,所以setState函数找不到
解决 在构造函数中 this.add = this.add.bind(this);
--------------------------------------- Redux默认只处理同步,异步任务需要react-thunk
安装redux
npm install redux --save
import { createStore } from 'redux' 这个函数用来创建store
import { counter,addGUN,removeGUN } from './index.redux.js' //导入自己写的reducer和action
let store = createStore(counter); //创建store
function render(){ //传入一个store,和addGUN,removeGUN,给组件,组件可以通过addGUN修改store
ReactDOM.render(<App store={store} addGUN={addGUN} removeGUN={removeGUN}/>,document.getElementById('root') )
}
render();
store.subscribe(render); //订阅,当组件的store(状态)发生改变时,执行render()
//组件内部 store.dispatch(addGUN( ))
----------------------------------安装 redux-thunk
npm install redux-thunk --save
导入 redux 中间件辅助函数
import { createStore , applyMiddleware } from './index.redux'
导入 thunk
import thunk from 'redux-thunk'
第一步 : 新建store时, 传入applyMiddleware ( thunk )
const store = createStore(counter, applyMiddleware( thunk ) );
第二步,编写异步函数
export function addGunAsync(){
return function(dispatch){ //返回一个函数,异步回调addGUN
setTimeout(()=>{
dispatch(addGUN());
},2000)
}
}
-------------------------------引入redux devtools 开发者工具(拓展程序)
//多引入一个compose
import {createStore , applyMiddleware , compose} from 'redux'
const reduxDevtools = window.devToolsExtension? window.devToolsExtension() :f=>f
//判断是否有window.devToolsExtension
const store = createStore(counter,compose(
applyMiddleware(thunk),
reduxDevtools
)) //创建store时传入 reduxDevtools
---------------------------------react-redux 优雅的结合react 和 redux ()
第一步:安装react-redux
npm install react-redux --save
第二步:使用react-redux
import { Provider } from 'react-redux' //引入Provider
第三步:使用Provider和Connect 忘记 store.subscribe
①Provider组件在应用最外层,传入store
ReactDOM.render(
<Provider store={store}> // store传入Provider,用Provider组件把App包起来,
<App/> //删除所有传入函数(addGUN()等)
<Provider />
,document.getElementById('root') )
②Connect 负责从外部获取组件需要参数,Connect 可以用装饰器的方式来写
在app.js引入Connect
import { Connect } from 'react-redux'
import { addGUN,removeGUN} from './index.redux.js'
const mapStateProps(state){
return {num:state}
}
const actionCreators = { addGUN, removeGUN } 向App传入action
App = connect( mapStatetoProps , actionCreators )(App) //把App 传入,返回新的App
connect 方法两个参数:第一个你需要把什么属性放在props里面
第二个你要什么方法。放到props里面,自动dispatch
------------------------------------react-Router4
与react-Router 2 很大不同
入门组件:
BrowserRouter
Router 路由对应渲染组件,可嵌套
Link 跳转专用
其他组件 :
Redirect <Redirect to='/someWhere'></Redirect>
Switch 只渲染命中的组件
<Switch></Switch>
路由使用:
安装----------- npm install react-router-dom --save
导入 import { BrowserRouter , Route ,Link} from 'react-router-dom'
ReactDOM.render(
<Provider store={store}>
<BrowserRouter> //BrowserRouter包含路由
<div>
<ul>
<li><Link to="/">一营</Link></li> //Link标签
<li><Link to="/er">二营</Link></li>
<li><Link to="/san">三营</Link></li>
</ul>
<Route path='/' component={App} exact ></Route> //根据Link跳转组件 exact完全匹配
<Route path='/er' component={Er}></Route>
<Route path='/san' component={San}></Route>
</div>
</BrowserRouter>
</Provider>,
document.getElementById('root')
)
Redirect
switch 只渲染命中的组件
---------------------------------------------route实现登录登出功能
登录,没有登录信息 统一跳转login
const LOGIN = 'LOGIN'; //定义两个action type
const LOGOUT = 'LOOUT';
//定义actiong构造函数
export login(login_uname)=>{
return { type:LOGIN, uname:login_uname }
}
export LOGOUT()=>{
return {type :LOGOUT }
}
export Auth_Reducer(state={ isLogin:false , uname:''},action)=>{
const {uname} = action;
switch(action.type){
case LOGIN:
return {...state,isLogin:true,uname:uname}
case LOGOUT:
return {...state,isLogin:false}
default:
return state
}
}
------------------------------------复杂的redux应用,多个reducer
怎么合并多个reducer?
① 新建一个reducer.js 文件保存所有reducer
②在reducer.js 引入 redux 的自带API
import { combineReducers } from 'redux';
import { reducer1 } from '/reducer1.js';
import { reducer2 } from '/reducer2./js';
export default combineReducers(
{ reducer1,reducer2}
);
③在createStore 文件中 import reducer from 'reducer.js'
-------------------------------------------------------项目骨架
src-----前端代码
server-------后端express
功能文件夹:component,container,reducers等
------------------------------------------------------页面骨架
router
-------------------------------------------------------其他
Mongodb 字段设计
axios 发送异步请求
redux 管理所有数据,组件尽量使用antd-mobile 弱化CSS
--------------------------------------------------打通前后端(axios)
如何发送?端口不一致,使用proxy配置转发
axios拦截器,统一loading处理
redux里使用异步数据,渲染页面
先启动服务器 node server.js 端口号
------安装axios(一个简洁好用的请求库)
npm install axios --save
●在package-json 最后加上"proxy":"http://localhost:9000"
(解决跨域问题,因为react端口在3000,Node在9000)
发送get请求: axios.get('/data').then((succ)=>{
console.log(succ.data);
})
发送post请求:axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
●使用axios配合redux ,向后台拿JSON更新store
export const updataData = (resData)=>{
return { type:GETJSON,data:resData }
} //定义action
export const getState = ()=>{
return dispatch=>{
axios.get('/data').then((succ)=>{
if(succ.status==200){
dispatch(updataData(succ.data)); //dispatch一个action
}
})
}
}
●使用axios拦截器,把所有请求前和相应后都拦截 都要做的事
新建一个config.js 作为 拦截器配置文件,在index.js导入这个文件
import axios from 'axios'
import { Toast } from 'antd-mobile'
axios.interceptors.request.use(function(config){
Toast.loading('加载中',0) //这个是动画效果,发请求之前显示动画
return config
})
axios.interceptors.request.use(function(){
Toast.hide() //相应结束以后隐藏
})