axios数据交互
-
安装axios
cnpm i axios --save
2.发起http请求
this.axios.get('/api/menulist').then(res=>{ console.log(res); }) this.axios.post('/api/menuedit', {pid: '345sdfj'}).then(res=>{ console.log(res); })
-
配置代理之手动配置
-
安装http-proxy-middleware
cnpm i http-proxy-middleware --save
-
创建setupProxy.js文件
在src下创建文件【setupProxy.js】js
const { createProxyMiddleware }=require("http-proxy-middleware"); module.exports=(app)=>{ app.use(createProxyMiddleware('/api', { target: 'http://localhost:3000',/*这里写自己的代理地址*/ changeOrigin: true,//允许跨域 })); } npm start #重启项目
fetch
fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对 象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点 像jQuery ajax。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使 用XMLHttpRequest对象。fetch有很多优势:
1语法简单,更加语义化。
2基于 标准Promise实现,支持async/await。
3提供了丰富的API
4脱离了XHR。fetch是 一种HTTP数据请求的方式,在react中,数据交互仍然使用axios
2-1.fetch之get请求
fetch('/api/menulist',{ headers:{ 'Content-Type':'application/x-www-form-urlencoded' } }).then(res=>{ return res.json(); }).then(res=>{ console.log(res); })
2-2.fetch之post请求
fetch('/api/menuedit',{ method:'POST',//post请求 headers:{ //请求头,不需要是可以不写使用默认值 'Content-Type':'application/x-www-form-urlencoded' }, //提交的数据 body:{ xx:xx, yy:yy } }).then(res=>res.json()) .then(res=>{ console.log(res); })
2-3.fetch之封装
// 封装fetch get post // 1.引入qs模块,也可以是JSON.stringify方法 import qs from 'qs' // 封装get /** * 参数一:url 请求的地址 */ export function myGet(url){ return fetch(url).then(res=>res.json()) } //封装post /** * 参数一:url: 请求的地址 * 参数二:data: 提交的数据 */ export function myPost(url,data){ return fetch(url,{ method:'post', body:qs.stringify(data) }).then(res=>res.json()) }
例子:
get请求
import {myGet, myPost} from '../myFetch' myGet('/api/menulist').then(res=>{ console.log(res); }) myPost('/api/roleadd',{xx:xx}).then(res=>{ console.log(res); })
redux
3-1.什么是redux
1.Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 2.redux构建一致化的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试。
3-2.为什么使用redux
1.React 只是 DOM 的一个抽象层,并不是 Web 应用的完整解决方案 2."只有遇到 React 实在解决不了的问题,你才需要 Redux 。 3.redux使用于多交互,多数据源
3-3.redux的三大原则
-
单一数据源
整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
-
state是只读的
唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。 eg: action = {type:'',data:''}
-
使用纯函数进行修改 纯函数的要求:函数的返回结果只依赖于它的参数、函数执行过程里面没有副作用
为了描述 action 如何改变 state tree ,你需要编写 reducers。
4.使用redux
4-1.安装
cnpm i redux --save
4-2.创建仓库store
-
store
Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。
// 1.引入redux import {createStore} from 'redux' // 创建store /** * 参数:reducer 纯函数 */ const store = createStore(reducer) export default store
4-3.state
-
state
Store对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。
// 2.创建state const initialState = { age: 18 num: 0 }
4-4.action
-
action
State 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了。 Action 是一个对象。其中的type属性是必须的,表示 Action 的名称。
const action = {type:'addNum'} store.dispatch(action)
4-5.reducer
-
reducer
Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。 Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。
// 声明一个reducer函数 /** * 参数一:state 只上一次更新的最新数据 * 参数二:action: 是一个json对象, 接受dispatch中的action * action = {type:'',[data:'']} */ const reducer = (state=initialState,action)=>{ switch (action.type) { case 'changeName': return { ...state, name:action.name } default: return state } }
5.store常用的方法
5-1.getState
-
获取store中状态数据的唯一方法
const {name,age} = store.getState()
5-2dispatch
-
将action作为参数触发纯函数的唯一方法
const action = {type:'addNum'} store.dispatch(action)
5-3.subscribe
-
订阅store中的状态数据
componentDidMount(){ store.subscribe(()=>{ this.setState(store.getState()) }) }
5-4.取消监听
// 组件挂载完成,监听订阅 componentDidMount(){ this.un = store.subscribe(()=>{ this.setState(store.getState()) }) } componentWillUnmount(){ // 取消订阅 this.un() }
actionCreator = { // changeName是一个函数,是actionCreator的一个方法. // 调用这个方法,就会返回一个对象,这个对象就是action changeName: (name) => ({ type: CHANGENAME, name: name }), changeAge: (age) => ({ type: CHANGEAGE, age: age }), }
ActionTypes:用来管理整个项目所有的action的type
export const CHANGEAGE = 'changeAge'; export const CHANGENAME = 'changeName';
import {CHANGEAGE, CHANGENAME} from './type' // 修改数据的纯函数:reducer const reducer = (state=initState, action)=>{ // action就是一个js的obj,一定会有一个属性叫type:{type: xxx, name: 'Jack'} switch (action.type) { case CHANGENAME: // 返回一个对象,作为新的state return { ...state, name: action.name } case CHANGEAGE: return { ...state, age: action.age } default: return state } }
import {CHANGEAGE, CHANGENAME} from '../store/type' actionCreator = { // changeName是一个函数,是actionCreator的一个方法. // 调用这个方法,就会返回一个对象,这个对象就是action changeName: (name) => ({ type: CHANGENAME, name: name }), changeAge: (age) => ({ type: CHANGEAGE, age: age }), }
将type.js中的变量导入到各个组件以及store中,保证整个项目的每个action的type属性都使用这里的变量,提高项目的可维护性。
Action Creator:action创建函数是将action作为一个函数进行封装,为了在store和view中进行方便调用
actionCreator = { // changeName是一个函数,是actionCreator的一个方法. // 调用这个方法,就会返回一个对象,这个对象就是action changeName: (name) => ({ type: CHANGENAME, name: name }), changeAge: (age) => ({ type: CHANGEAGE, age: age }), }
ActionTypes:用来管理整个项目所有的action的type
export const CHANGEAGE = 'changeAge'; export const CHANGENAME = 'changeName';
import {CHANGEAGE, CHANGENAME} from './type' // 修改数据的纯函数:reducer const reducer = (state=initState, action)=>{ // action就是一个js的obj,一定会有一个属性叫type:{type: xxx, name: 'Jack'} switch (action.type) { case CHANGENAME: // 返回一个对象,作为新的state return { ...state, name: action.name } case CHANGEAGE: return { ...state, age: action.age } default: return state } }
import {CHANGEAGE, CHANGENAME} from '../store/type' actionCreator = { // changeName是一个函数,是actionCreator的一个方法. // 调用这个方法,就会返回一个对象,这个对象就是action changeName: (name) => ({ type: CHANGENAME, name: name }), changeAge: (age) => ({ type: CHANGEAGE, age: age }), }
将type.js中的变量导入到各个组件以及store中,保证整个项目的每个action的type属性都使用这里的变量,提高项目的可维护性。