【React+TS】从零开始搭建react+typescript+router+redux+less+px2rem自适应+axios反向代理+别名@+Antd-mobile

2023-11-03

一、通过create-react-app脚手架创建项目

npx create-react-app testproject --template typescript

 在vscode中打开项目,可以看到顺利生成了react项目且组件的后缀为tsx,此时说明成功创建了react+typescript项目的雏形

 在项目根目录下,运行npm run start,成功启动项目

npm start

 二.配置路由

npm i react-router-dom@5.2.0 react-router-config @types/react-router-config @types/react-router-dom -S

src目录下创建views文件夹,views内创建Home,Contact,About,Navbar四个tsx文件,其中Navbar用来控制路由,其他三个页面用来展示

Home:

import React, { Component } from "react";
 
export default class Home extends Component {
  render() {
    return (
      <div className="home">
        <div className="container">
          <h3 className="center"> Home页面</h3>
          <p>欢迎来到首页</p>
        </div>
      </div>
    );
  }
}

Contact:

import React, { Component } from "react";
 
export default class Contact extends Component {
  render() {
    return (
      <div className="contact">
        <div className="container">
          <h3 className="center"> Contact页面</h3>
          <p>欢迎来到联系我们页面!</p>
        </div>
      </div>
    );
  }
}

About:

import React, { Component } from "react";
 
export default class About extends Component {
  render() {
    return (
      <div className="about">
        <div className="container">
          <h3 className="center"> About页面</h3>
          <p>欢迎来到关于我们页面!</p>
        </div>
      </div>
    );
  }
}

Navbar:

import React, { Component } from "react";
 
export default class Navbar extends Component {
    render() {
        return (
            <nav className="nav-wrapper">
                <div className="list">
                    <ul>
                        <li><a href='/'>Home</a></li>
                        <li><a href='/about'>About</a></li>
                        <li><a href='/contact'>Contact</a></li>
                    </ul>
                </div>
            </nav>
        )
    }
}

 src目录下创建routes文件夹,同时创建index.ts,使用RouteConfig对路由进行统一管理

// 导入路由组件
import Home from '../views/Home'
import About from '../views/About'
import Contact from '../views/Contact'
// 导入路由管理工具
import {RouteConfig} from 'react-router-config'
 
const routes:RouteConfig = [
  {
    path:'/',
    exact:true,
    component:Home
  },
  {
    path:'/about',
    exact:true,
    component:About
  },
  {
    path:'/contact',
    exact:true,
    component:Contact
  }
]
 
export default routes;

  App.tsx中引入Route,Navbar和路由管理工具

import React from "react";
// 引入路由导航栏
import Navbar from "./views/Navbar";
// 引入routes组件
import routes from "./routes";
// 引入包管理工具
import { renderRoutes, RouteConfig } from "react-router-config";
import "./App.css";
 
function App() {
  return (
    <div className="App">
      <Navbar />
 
      {/* 设置routes的类型为RouteConfig[],否则报错 */}
      {renderRoutes(routes as RouteConfig[])}
    </div>
  );
}
 
export default App;

 根目录index.tsx中这样定义

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter as Router } from "react-router-dom";
 
ReactDOM.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
  </React.StrictMode>,
  document.getElementById("root")
);
 
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

至此,路由配置就完成了,启动项目如果出现以下错误,

 运行命令

npm i react-router@5.2.0 -s

然后重新运行即可,你的页面应该是这样的

  有点难看是吧,我们给App添加一点样式

* {
  padding: 0;
  margin: 0;
}
 
h1 {
  text-align: center;
  font-size: 45px;
  font-family: Arial, Helvetica, sans-serif;
  color: rgb(6, 0, 32);
  padding: 40px;
}
 
.list {
  display: flex;
  justify-content: center;
  width: 100%;
}
 
.list ul li {
  list-style: none;
  margin: 42px;
  text-align: center;
}
 
a {
  text-decoration: none;
  color: rgb(0, 0, 0);
  font-size: 18px;
  font-family: Arial, Helvetica, sans-serif;
  padding: 14px 25px;
  background-color: transparent;
  border: 2px solid rgb(12, 0, 66);
}
 
a:hover {
  background-color: rgb(12, 0, 66);
  color: rgb(255, 255, 255);
}

 三、配置less

第一种方式:暴露配置的方式 在要暴露的文件夹里打开Git base Here

git add .
git commit -m 'aaa'

之后在命令提示框

npm run eject

此时项目多出了config文件夹

 安装lessless-loader

npm i less less-loader -S

仿照sass修改config目录下的webpack.config.js:

1. 找到config目录下的webpack.config.js文件,在50-70行之间有个cssRegex,在此处添加

// less
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;

 2. 在webpack.config.js文件500多行有个sassRegex,模仿写对应的lessRegex

// less
            {
              test: lessRegex,
              exclude: lessModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                },
                'less-loader'
              ),
              sideEffects: true,
            },
            // less
            {
              test: lessModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  modules: true,
                  getLocalIdent: getCSSModuleLocalIdent,
                },
                'less-loader'
              ),
            },

3.重新启动项目,创建less文件并引入

样式生效,说明less配置成功

 

 四、配置axios和反向代理

1. 安装axios 和 http-proxy-middleware(后面反向代理会用到)

npm i axios http-proxy-middleware -s

2. 在src目录下创建api文件夹,然后创建 index.ts 和 request.ts 文件

index:

import { Service } from "./request";
interface searchConfig {
    page:   number
    mod: string
}
interface getConfig {
    page: number
}
export function searchCar(config: searchConfig) {
    const params: any = new URLSearchParams()

    params.append('page', config.page);
    params.append('mod', config.mod);

    return Service({
        url: "/api/oldcar/searchCar",
        data: params
    })
}
export function getCarList(config: getConfig) {
    const params: any = new URLSearchParams()
    params.append('page', config.page);
    return Service({
        url: "/api/oldcar/getCarList/",
        data: params
    })
}

request:

import axios from "axios";
export const Service = axios.create({
    timeout: 3000, //延迟时间
    method: 'POST',
    headers: {
        "content-Type": "application/x-www-form-urlencoded",
        "pc-token": "4a82b23dbbf3b23fd8aa291076e660ec", //后端提供
    }
})
// 请求拦截
Service.interceptors.request.use(config => {
    return config
})
// 响应拦截
Service.interceptors.response.use(response=>{
    return response.data
},err=>{
    console.log(err)
})

3. 配置代理,可以访问到后台的服务器地址

在src文件夹中创建setupProxy.js内容配置如下

const { createProxyMiddleware } = require('http-proxy-middleware')
module.exports = function (app) {
  app.use(
    createProxyMiddleware('/api', {
      target: 'http://www.ibugthree.com',
      secure: false,
      changeOrigin: true,
      pathRewrite: {
        '^/api': ''
      }
    })
  )
}

 到这里所有配置就基本完成,在组件中调用即可

import React, { Component } from "react";
import "./contact.scss";
//导入要使用的接口
import { getCarList } from "../api/index";
 
export default class Contact extends Component {
  // 定义方法
  getList() {
    getCarList({ page: "1" }).then((res) => console.log(res));
  }
  render() {
    return (
      <div className="contact">
        <div className="container">
          <h3 className="center"> Contact页面</h3>
          <p>欢迎来到联系我们页面!</p>
          {/* 点击事件调用 */}
          <button onClick={this.getList}>获取数据</button>
        </div>
      </div>
    );
  }
}

 五、配置redux

1. 安装redux

npm i redux react-redux -s

2.在src路径下创建store文件夹,文件假中创建两个文件action.ts和index.ts两个文件

action中定义type,然后返回设置状态的type和函数

export const SET_AGE = "set_age";
export const SET_NAME = "set_name";
 
export const setAge = function (n: number) {
  return {
    type: SET_AGE,
    n: n,
  };
};
export const setName = function (name: string) {
  return {
    type: SET_NAME,
    name: name,
  };
};

index文件中取出redux中的createStore,以及action中的type,最后需要将createStore返回出去,并且需要传递一个函数,定义这个函数时有两个参数,一个是状态,一个是action,使用switch判断action中的type,当所有条件都不成立时,将所有的状态返回,有条件成立时,就通过扩展运算符将state展开,并且对age进行操作(...state);
 

import { createStore } from "redux";
import { SET_AGE, SET_NAME } from "./action";
 
interface User {
  name: string;
  age: number;
}
 
const common: User = {
  name: "张三123",
  age: 18,
};
 
function user(state = common, action: any) {
  switch (action.type) {
    case SET_AGE:
      return {
        ...state,
        age: state.age + action.n,
      };
    case SET_NAME:
      return {
        ...state,
        name: action.name,
      };
    default:
      return state;
  }
}
 
export default createStore(user);

3. 在主入口文件index.tsx中进行redux的连接和store的引用

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
// 引入路由组件
import { BrowserRouter as Router } from "react-router-dom";
// 引入移动端自适应
import "lib-flexible";
//引入rootReducer组件
import { Provider } from "react-redux";
import store from "./store";
 
ReactDOM.render(
  <React.StrictMode>
    {/* provider组件将所有的组件包裹起来,用绑定属性的形式绑定store到组件中 */}
    <Provider store={store}>
      <Router>
        <App />
      </Router>
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);
 
reportWebVitals();

4. 在App中进行配置

import React from "react";
// 引入路由导航栏
import Navbar from "./views/Navbar";
// 引入routes组件
import routes from "./routes";
// 引入包管理工具
import { renderRoutes, RouteConfig } from "react-router-config";
import "./App.css";
// 引入connect连接组件
import {connect} from "react-redux"
 
 
function App() {
  return (
    <div className="App">
      <Navbar />
      {/* 设置routes的类型为RouteConfig[],否则报错 */}
      {renderRoutes(routes as RouteConfig[])}
    </div>
  );
}
 
//进行连接
export default connect((props,state)=>Object.assign({},props,state),{})(App);

5.组件中使用redux

    1. 引入connect和action中的方法

    2. 定义props和state类型

    3. 修改render中的html结构,定义属性和方法调用

    4. connect连接属性并导出

import React, { Component } from "react";
import "./about.less";
// redux
import { connect } from "react-redux";
import { setName, setAge } from "../store/action";
 
interface Props {
  setAge: Function;
  setName: Function;
  age: number;
  name: string;
}
 
interface State {}
 
class About extends Component<Props,State> {
  refs:any = React.createRef()
  // eslint-disable-next-line @typescript-eslint/no-useless-constructor
  constructor(props:Props){
    super(props)
  }
  changeAge(){
    this.props.setAge(1);
    console.log(this.props);
  }
  changeName(){
    let name:number = this.refs.value
    this.props.setName(name)
    console.log(this.refs);
    this.refs.value = ''
  }
  render() {
    return (
      <div className="about">
        <div className="container">
          <h3 className="center"> About页面</h3>
          <p>欢迎来到关于我们页面!</p>
        </div>
        <div>
          <p>名字是:{this.props.name}</p>
          <input ref={(input: HTMLInputElement) => this.refs = input}  type="text" /> 
          <button onClick={this.changeName.bind(this)}>修改姓名</button>
          <p>年龄是:{this.props.age}</p> 
          <button onClick={this.changeAge.bind(this)}>修改年龄</button>
        </div>
      </div>
    );
  }
}
 
export default connect((props,state)=>Object.assign({},props,state),{
  setAge,setName
})(About);

六、 配置别名@

一、暴露方法

1.打开 config 文件夹下的 webpack.config.js 文件

 2.搜索 alias

 

 3.参照如下格式,设置路径别名

alias: {
        // Support React Native Web
        // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
        'react-native': 'react-native-web',
        // Allows for better profiling with ReactDevTools
        ...(isEnvProductionProfile && {
          'react-dom$': 'react-dom/profiling',
          'scheduler/tracing': 'scheduler/tracing-profiling',
        }),
        ...(modules.webpackAliases || {}),
        // 文件路径别名
        '@': path.resolve(__dirname, '../src'),
        '@view': path.resolve(__dirname, '../src/view'),
      },

七、配置antd-mobile

1.在项目中安装antd-mobile 使用

npm install antd-mobile
//或
yarn add antd-mobile

2.在项目中Home.tsx文件中导入要使用的组件

import React, { Component } from "react";
//使用组件直接在组件中进行使用即可
import { Button } from 'antd-mobile';
 
export default class Home extends Component {
  render() {
    return (
      <div className="home">
        <div className="container">
          <h3 className="center"> Home页面</h3>
          <p>欢迎来到首页</p>
          <Button color='primary'>按钮</Button>
        </div>
      </div>
    );
  }
}

完成之后,你就能在react项目使用antd-mobile的样式文件进行构建自己的页面了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【React+TS】从零开始搭建react+typescript+router+redux+less+px2rem自适应+axios反向代理+别名@+Antd-mobile 的相关文章

随机推荐

  • mysql generator 配置_MyBatis Generator 超详细配置

    想快速开始 请直接拉到最后 看整体配置 MyBatis Generator 是 MyBatis 提供的一个代码生成工具 可以帮我们生成 表对应的持久化对象 po 操作数据库的接口 dao CRUD sql的xml mapper MyBati
  • LocalDate、LocalTime、LocalDateTime介绍

    一 Date与LocalDate LocalTime LocalDateTime互转 1 Date转LocalDate LocalTime LocalDateTime Date date new Date Instant instant d
  • 基于粒子群优化改进的SIFT算法实现SAR图像配准附MATLAB代码

    基于粒子群优化改进的SIFT算法实现SAR图像配准附MATLAB代码 图像配准是合成孔径雷达 SAR 图像处理中的重要任务之一 它的目标是对两幅或多幅图像进行对齐 使得它们在几何上或像素级别上达到最佳匹配 在这篇文章中 我们将介绍基于粒子群
  • 元素层叠总结

    重点 在相同的层叠环境及优先级下 inline inline block元素的层叠顺序高于block元素 详解链接 https www codercto com a 23706 html 本文转载自 https juejin im post
  • SQL根据不同状态类型动态使用不同排序方式

    SQL根据不同状态类型使用不同排序方式 1 业务场景 1 1 需求 默认按状态值为1 2 3 5 4的顺序排序 状态相同时 状态为1 则按创建时间倒序 状态为2 则按开始时间正序 1 2 示例SQL select from t table
  • 【FPGA面试题(八)】—— 实现简单的FIFO

    FPGA面试题 八 实现简单的FIFO 在FPGA的数字电路中 FIFO First In First Out 是一个非常基础且重要的模块 它可以像一个队列一样存储数据并按照先进先出的顺序进行读取 实现FIFO是FPGA工程师面试过程中经常
  • notepad: 怎么在notepad里面,将字符串替换成换行

    用Notepad 可以 利用查找和替换功能 选择正则表达式 查找目标框里输入你想要替换的字符串 替换为框里输入 r 点击替换即可 这是个 很强大的功能 利用还它可以批量替换任何字符串 比如你链接是123 123 123 123这样不换行的
  • python 实现 熵值法 确定指标权重

    步骤 设指标共p个 评价对象共g个 则构成评价值 得分 矩阵如下 xj i 表示评价对象j在指标i上的评价值 j 1 2 g i 1 2 p 指标i对应的熵值为ei的计算公式如下 根据熵值来计算指标i的权重wi 计算公式如下 程序 4个指标
  • pm2 进程管理工具,相关命令

    1 pm2需要全局安装 npm install g pm2 2 进入项目根目录 2 1 启动进程 应用 pm2 start bin www 或 pm2 start app js 2 2 重命名进程 应用 pm2 start app js n
  • minicom安装、配置和使用

    在开发过程中 我们经常需要通过串口连接Android开发板的底层系统 Linux QNX 等 minicom是一个常用串口连接终端软件 在命令行终端下通过文本界面进行操作使用 安装 sudo apt install minicom 配置 首
  • BufferedReader与FileReader及FileInputStream

    BufferedReader 是缓冲字符输入流 它继承于Reader BufferedReader 的作用是为其他字符输入流添加一些缓冲功能 BufferedReader的作用 从字符输入流中读取文本 缓冲各个字符 从而实现字符 数组和行的
  • C# Ocr离线式识别,文字提取,(附源码下载)

    源代码下载 效果图 文字内容提取后填充 JObject obj ocr GeneralBasic bt ops this richTextBox1 Text string str if obj Count gt 0 JArray jo JA
  • LeetCode - 移除元素

    一 题目描述 给定一个数组 nums 和一个值 val 你需要原地移除所有数值等于 val 的元素 返回移除后数组的新长度 不要使用额外的数组空间 你必须在原地修改输入数组并在使用 O 1 额外空间的条件下完成 元素的顺序可以改变 你不需要
  • GBase8a MPP Cluster 安装部署——操作系统配置建议

    编写目的 本文档面向GBase 8a产品的售后人员 用户使用人员 以及广大GBase 8a感兴趣的技术人员 以便用于指导其更好的完成GBase8a MPP Cluster 安装部署工作 对硬件配置 网络环境 操作系统及软件配置等系统实施过程
  • vue 接口数据返回之后再渲染页面_Vue怎么让数据请求成功以后再渲染页面?

    需求如下 进入页面有一个检测按钮 点击即可向后端请求数据 进入页面如果不点击检测 则显示如下 点击检测 如果返回的是正常的状态则显示 如果返回的状态是异常 则显示 目前有个BUG 就是点击检测的时候 先从变为 然后马上变为 因为逻辑里面我是
  • IJCAI2023 Summary Reject公布

    点击文末公众号卡片 找对地方 轻松参会 北京时间2023年2月25日上午6点四十左右 cmt上状态已变 分为awaiting list 和reject 此前不少人预测2月24日晚上八点或凌晨两点左右出 截至2023年2月25日 7 16 a
  • 调用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()时遇到的一些问题

    之前在其他地方写的 一直要求手机验证 之前能跳过 麻烦点就麻烦点了 今天编辑文章的时候直接不能改了 无奈 如果手动调用 TransactionAspectSupport currentTransactionStatus setRollbac
  • mybatis获取插入数据时自动生成的主键id

    mapper文件 void insert Map
  • LaTeX

    简介 首先要介绍一下我用的Visio文件转为 eps的办法 vsd 文件 利用Visio打开 然后另存为 选择存为 pdf文件 pdf文件 利用Inkscape打开 然后另存为 选择存为 eps格式 之前一直用visio2010版 然后按照
  • 【React+TS】从零开始搭建react+typescript+router+redux+less+px2rem自适应+axios反向代理+别名@+Antd-mobile

    一 通过create react app脚手架创建项目 npx create react app testproject template typescript 在vscode中打开项目 可以看到顺利生成了react项目且组件的后缀为tsx