这里是后台搭建目录的后半部分
- 安装 react-redux
- 安装 axios
- 安装 lottie
- 网络加载加载
(一) 安装 react-redux
(1) 安装包依赖
yarn add redux -S
yarn add react-redux -S
(2) 在 src 目录下创建一个 store 文件夹 里面创建一个 index.js 文件作为公共仓库
- 调试的时候要借助 redux 工具,store 里面必须要加入 window 开头的
import { createStore } from 'redux'
//引入reducer
import reducer from './reducer'
//放入reducer
const store = createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
export default store
(3) 在 src 目录下创建 actiontypes 文件
export const CHANGE_VALUE = 'change_value'
export const CLICK_CHANGE = 'click_change'
export const DELETE_ITEM = 'delete_item'
//正式的开始
export const CHANGE_LOADING = 'change_loading'
(4) 在 src 目录下面创建 actioncreater.js 文件
import {
CHANGE_VALUE,
CLICK_CHANGE,
DELETE_ITEM,
CHANGE_LOADING,
} from './actiontypes'
export const ACTION_CHANGE_VALUE = (value) => {
return {
type: CHANGE_VALUE,
value,
}
}
export const ACTION_CLICK_CHANGE = () => {
return {
type: CLICK_CHANGE,
}
}
export const ACTION_DELETE_ITEM = (value) => {
return {
type: DELETE_ITEM,
value,
}
}
//正式的开始
export const ACTION_CHANGE_LOADING = (value) => {
return {
type: CHANGE_LOADING,
value,
}
}
(5)在 src 目录下创建 reducer.js 文件
它里面接收两个参数(state,action)
state 就是获取所有的公共数据
import {
CHANGE_VALUE,
CLICK_CHANGE,
DELETE_ITEM,
CHANGE_LOADING,
} from './actiontypes'
const defaultState = {
inputValue: '123',
list: [
'Racing car sprays burning fuel into crowd.',
'Japanese princess to wed commoner.',
'Australian walks 100km after outback crash.',
'Man charged over missing wedding girl.',
'Los Angeles battles huge wildfires.',
],
loadingFlag: false,
}
export default (state = defaultState, action) => {
//这里判断action的type然后在返回state
if (action.type === CHANGE_VALUE) {
let newresult = JSON.parse(JSON.stringify(state)) //必须要重新生成一个新的对象,也不能使用Object.asign这样有的时候不起作用,而且每个判断里面必须有返回值
newresult.inputValue = action.value
return newresult
}
if (action.type === CLICK_CHANGE) {
let newData = JSON.parse(JSON.stringify(state))
if (newData.inputValue != null) {
newData.list.push(newData.inputValue)
newData.inputValue = ''
}
return newData
}
// 这里就是删除方法,必须返回新数据
if (action.type === DELETE_ITEM) {
let newData = JSON.parse(JSON.stringify(state))
newData.list.splice(action.value, 1)
return newData
}
//----------正式开始------------
if (action.type === CHANGE_LOADING) {
let newData = JSON.parse(JSON.stringify(state))
newData.loadingFlag = action.value
return newData
}
return state
}
(6) 在 src 目录下面的 index.js 里面写
import React from 'react'
import ReactDOM from 'react-dom'
import './reset.css'
import RouterDom from './router.js'
import { Provider } from 'react-redux'
import store from './store/index'
ReactDOM.render(
<Provider store={store}>
<RouterDom />
</Provider>,
document.getElementById('root')
)
(7) 组件里面使用
- 修改里面的变量即可
//必须要引入connect
import { connect } from 'react-redux'
//然后在类的外面定义两个常量,两个常量都是方法,返回的都是对象
const mapStateToProps = (state) => {
return {
inputValue: state.inputValue,
list: state.list,
}
}
const mapDispatchToProps = (dispatch) => {
return {
handleChange(e) {
let value = e.target.value
const action = {
type: 'change_value',
value,
}
dispatch(action)
},
changeList() {
let action = {
type: 'change_list',
}
dispatch(action)
},
deleteItem(index) {
let action = {
type: 'deleteItem',
value: index,
}
console.log(index)
dispatch(action)
},
}
}
//最后利用store挂钩
export default connect(
mapStateToProps, //这里面放的是数据
mapDispatchToProps //里面放的是操作的数据的方法
)(TodoList)
(二) 安装 lottie
(1) 安装包依赖
yarn add react-lottie -S
(2) 封装 lottie 核心组件
import React from 'react'
import Lottie from 'react-lottie'
import * as animationData from '../../utils/data.json'
export default class LottieControl extends React.Component {
constructor(props) {
super(props)
this.state = { isStopped: false, isPaused: false }
}
render() {
const loadingPosition = {
position: 'fixed',
left: '50%',
top: '50%',
marginLeft: '-250px',
marginTop: '-250px',
zIndex: 999,
}
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animationData.default,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice',
},
}
return (
<div>
<Lottie
options={defaultOptions}
height={400}
width={400}
style={loadingPosition}
isStopped={this.props.loadingFlag}
/>
</div>
)
}
}
(3) 给核心组件套个壳子,属于 page
import React, { Component, Fragment } from 'react'
import LoadingComponent from '../components/Loading/loading.js'
import { connect } from 'react-redux'
class Loading extends Component {
constructor(props) {
super(props)
this.state = {}
}
render() {
const wrap = {
width: '100vw',
height: '100vh',
position: 'fixed',
top: '0px',
bottom: '0px',
background: 'rgba(0,0,0,0.7)',
}
return (
<Fragment>
<div style={wrap}>
<LoadingComponent
loadingFlag={this.props.loadingFlag}
></LoadingComponent>
</div>
</Fragment>
)
}
}
const mapStateToProps = (state) => {
return {
loadingFlag: state.loadingFlag,
}
}
const mapDispatchToProps = (dispatch) => {
return {}
}
//最后利用store挂钩
export default connect(
mapStateToProps, //这里面放的是数据
mapDispatchToProps //里面放的是操作的数据的方法
)(Loading)
(4) 页面上引用的时候必须放到 APP.js 里面
import React, { Component, Fragment } from 'react'
import Loading from './pages/Loading.js'
import { connect } from 'react-redux'
class App extends Component {
constructor(props) {
super(props)
this.state = {
message: '加载',
}
}
render() {
const { loadingFlag } = this.props
return (
<Fragment>
{loadingFlag ? <Loading></Loading> : null}
{this.props.children}
</Fragment>
)
}
}
const mapStateToProps = (state) => {
return {
loadingFlag: state.loadingFlag,
}
}
const mapDispatchToProps = (dispatch) => {
return {}
}
//最后利用store挂钩
export default connect(
mapStateToProps, //这里面放的是数据
mapDispatchToProps //里面放的是操作的数据的方法
)(App)
(三) 安装 axios 封装 axios
(1) 安装包依赖
yarn add axios -S
(2) 封装 axios
window.location.href 后续替换
url 是区分不同环境加载不同配置文件的方法
网络加载的时候改变 store 里面的值
// request.js
import axios from 'axios'
import store from '../store/index.js'
import { ACTION_CHANGE_LOADING } from '../store/actioncreaters'
import url from '../config.js'
/** **** request拦截器==>对请求参数做处理 ******/
axios.interceptors.request.use(
(config) => {
// 加载
store.dispatch(ACTION_CHANGE_LOADING(true))
let value = sessionStorage.getItem('token') || '123'
if (value) config.headers.Authorization = value
return config
},
(error) => {
return Promise.reject(error)
}
)
/** **** respone拦截器==>对响应做处理 ******/
axios.interceptors.response.use(
(response) => {
store.dispatch(ACTION_CHANGE_LOADING(false))
return response
},
(error) => {
// 错误提醒
store.dispatch(ACTION_CHANGE_LOADING(false))
const { status } = error.response
if (status === 401) {
// 清除token
sessionStorage.clear()
window.location.href = url.homeurl
}
if (status === 404) {
window.location.href = url.homeurl
}
// 页面跳转
//router.push('/login')
return Promise.reject(error)
}
)
export default axios