工程目录图
【重点】:启动项目命令 npm run dev
or yarn dev
整体结构说明
src目录下的说明
文件下的代码及引用关系
- src
- assets
- 页面使用
import "./assets/css/base.scss" //根据对应页面写路径
common
- login.ts
// data定义 const state = { "loginInfo": { "userName": '', "userPassword": '', "remember": false }, }; export default state;
components
- common
- footer
- header
- home
- login
- login.tsx
import React, { Component } from 'react' // 使用antd组件库 import * as ant from 'antd'; // 使用定义是的data import State from '../../common/login' // 使用封装的请求方法 import { login } from '../../request/api'; // 使用redux import { connect } from 'react-redux'; class index extends Component { constructor(props:any) { super(props) this.state = State } // 双向绑定 onchange(key: any, val: any) { let {loginInfo}:any=this.state this.setState({ loginInfo: Object.assign({},loginInfo, { [key]: val }) }) console.log(loginInfo) } // login事件 getLogin() { let {loginInfo}:any =this.state login({ loginInfo },{}).then((res) => { console.log(res); }) } render() { let { loginInfo }: any = this.state console.log(this.props); return ( <div> <ant.Input type="text" value={loginInfo.userName} name="userName" onChange={this.onchange.bind(this,"userName")} placeholder="输入用户ID"></ant.Input> <ant.Input.Password value={loginInfo.userPassword} name="userPassword" onChange={this.onchange.bind(this,"userPassword")} placeholder="输入用户密码"></ant.Input.Password> <br /> <ant.Button onClick={() => {this.getLogin() }}>登录</ant.Button> </div> ) } } // 建立一个从state对象到props对象的映射关系 function mapStateToProps(state:any) { return Object.assign({}, state) } export default connect(mapStateToProps)(index)
redux
- home
- login
- action
-// 事件处理 修改state,创建action对象 import * as Types from '../actionType/loginType'; export const addCount = (value:any) => { return { type: Types.SETNAME, value } }
- actionType
// 定义类型 export const SETNAME = 'SETNAME'; // 定义数据 export const initState = { loginInfo: { "userName": '李san' }, }
- reducer
import * as Types from '../actionType/loginType'; const initState = Types.initState const reducer = (preState = initState, action:any) => { let { type } = action; switch (type) { case Types.SETNAME: return { loginInfo: Object.assign({}, preState.loginInfo, { "userName": action.value }) }; default: return preState } } export default reducer
- index.ts
import * as actions from './action/login'; import Login from './reducer/loginReducer'; export { actions, Login }
- store.ts
// 根据reducer来生成store仓库,调用入口 import { c
request
- api.ts
import { get, post } from './http' export const login = (params:any, headers:any) => post('raku0000/login', params,);
- http.ts
import axios from "axios"; axios.create({ timeout: 50000, baseURL:"http://localhost:3000" }) /** * http request 拦截器 **/ axios.interceptors.request.use( (config) => { config.data = JSON.stringify(config.data); config.headers = { "Content-Type": "application/json", }; return config; }, (error) => { return Promise.reject(error); } ); /** * http response 拦截器 */ axios.interceptors.response.use( (response) => { console.log(response) return response; }, (error) => { console.log("请求出错:", error); } ); /** * 封装get方法 * @param url 请求url * @param params 请求参数 * @returns {Promise} */ export function get(url:string, params = {}) { return new Promise((resolve, reject) => { axios.get(url, { params: params, }).then((response) => { landing(url, params, response.data); resolve(response.data); }) .catch((error) => { reject(error); }); }); } /** * 封装post请求 * @param url * @param data * @returns {Promise} */ export function post(url:string, data:any) { return new Promise((resolve, reject) => { axios.post(url, data).then( (response) => { //关闭进度条 resolve(response.data); }, (err) => { reject(err); } ); }); } /** * 封装patch请求 * @param url * @param data * @returns {Promise} */ export function patch(url:string, data = {}) { return new Promise((resolve, reject) => { axios.patch(url, data).then( (response) => { resolve(response.data); }, (err) => { msag(err); reject(err); } ); }); } /** * 封装put请求 * @param url * @param data * @returns {Promise} */ export function put(url:string, data = {}) { return new Promise((resolve, reject) => { axios.put(url, data).then( (response) => { resolve(response.data); }, (err) => { msag(err); reject(err); } ); }); } //统一接口处理,返回数据 export default function (fecth:any, url:string, param:any) { let _data = ""; return new Promise((resolve, reject) => { switch (fecth) { case "get": console.log("begin a get request,and url:", url); get(url, param) .then(function (response) { resolve(response); }) .catch(function (error) { console.log("get request GET failed.", error); reject(error); }); break; case "post": post(url, param) .then(function (response) { resolve(response); }) .catch(function (error) { console.log("get request POST failed.", error); reject(error); }); break; default: break; } }); } //失败提示 function msag(err:any) { if (err && err.response) { switch (err.response.status) { case 400: alert(err.response.data.error.details); break; case 401: alert("未授权,请登录"); break; case 403: alert("拒绝访问"); break; case 404: alert("请求地址出错"); break; case 408: alert("请求超时"); break; case 500: alert("服务器内部错误"); break; case 501: alert("服务未实现"); break; case 502: alert("网关错误"); break; case 503: alert("服务不可用"); break; case 504: alert("网关超时"); break; case 505: alert("HTTP版本不受支持"); break; default: } } } /** * 查看返回的数据 * @param url * @param params * @param data */ function landing(url:string, params:any, data:any) { if (data.code === -1) { } }
router
- index.ts
import { useRoutes } from 'react-router-dom' import constantRouteMap from './index.config' const RouterView = () => useRoutes(constantRouteMap) export default RouterView
- index.config.ts
import * as React from 'react'; import type { RouteObject } from "react-router-dom"; const Login =React.lazy(()=>import('../components/login/index')) const constantRouteMap: RouteObject[] = [ { path: '/', element: <Login />, } ] export default constantRouteMap;
- utils
- App.tsx
import * as React from 'react'; import { BrowserRouter } from 'react-router-dom'; // 引入router import RootRoutes from './router/index'; import "./assets/css/base.scss" const App: React.FC = () => ( <BrowserRouter> <RootRoutes/> </BrowserRouter> ); export default App;
- main.tsx
import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import 'antd/dist/antd.css'; ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( <React.StrictMode> <App /> </React.StrictMode> )