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

​​​​前提相关:

npm install -g create-react-app    创建React项目

create-react-app -V        检测React版本号

npm install react@17.0.2 react-dom@17.0.2 --save  降低版本

在创建该项目前我们需要准备的是:

版本号不低于6.14.8的node.js 以及 git

node.js官方网址:Node.js 中文网        这里我们推荐下载长期支持版本

一、通过create-React-app 脚手架搭建项目

1.打开目标文件夹 在地址栏中输入cmd 呼出命令提示窗

2.输入React脚手架项目搭建命令,我们需要注意的是项目名称中不能出现大写字母

npx create-react-app vipshop --template typescript

此时回车就可以正式创建React项目了,当出现如下图中所示的Happy hacking就说明下载乘成功,然后我们进入我们的VsCode中进入我们的目录中,就可以看到我们生成的React项目,如出现后缀名为.tsx的文件就说明我们的React+TypeScript项目雏形搭建完成。

 二、运行我们的React脚手架

进入项目跟目录下,输入运行命令 :npm start

npm start

三、配置React路由

第一步、

  • 在cmd中输入npm路由下载路由指令
npm i react-router-dom@5.2.0 react-router@5.2.0 react-router-config @types/react-router-config @types/react-router-dom -S

第二步、

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

  •  Home.tsx
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.tsx
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.tsx
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.tsx
import React, { Component } from "react";
import { Link } from "react-router-dom";
export default class Navbar extends Component {
    render() {
        return (
            <nav className="nav-wrapper">
                <div className="list">
                    <ul>
                        <li><Link to='/'>Home</Link></li>
                        <li><Link to='/about'>About</Link></li>
                        <li><Link to='/contact'>Contact</Link></li>
                    </ul>
                </div>
            </nav>
        )
    }
}

第三步、

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

  • index.ts
// 导入路由组件
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;

第四步、

  • 在src根目录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;

 第五步、

  • 在src根目录下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")
);
reportWebVitals();

第六步、

  • 此时我们的路由搭载完毕 npm start 启动项目查看效果
  • 项目启动后效果应该如下图所示

 此时我们看到样式可能有点不尽人意,我面添加一点样式 

第七步、

在src根目录下 App.css中添加如下样式

* {
  padding: 0;
  margin: 0;
}

.container {
  text-align: center;
}

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 {
  float: left;
  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 add .
git commit -m "暴露"
npm run eject

在第三个指令确认后,会出现选项 我们输入y 回车即可

  • 此时项会出现一个config文件夹

 第二步、

  • 安装less和less-loader命令: npm i less less-loader -S
npm i less less-loader -S

第三步、

  • 找到config文件夹目录下wedpack.config.js文件,在70行左右有个cssRegex,在此处添加

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

第四步、

  • 在wedpack.config.js文件530行左右有个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'
              ),
            },

第五步、

  • 在views文件夹下创建一个about.less文件,并写入如下代码:

.about{
    .container{
        font-size: 30px;
        p{
            color: red;
        }
    }
    .box{
        text-align: center;
    }
}
  • 在views文件夹下 About.tsx中引入
import "./about.less"

  •  此时我们输入npm start 打开项目应该是这样的

 当我们看到这样的页面时就说明我们的less配置完毕

配置sass和px转rem自适应适配

第一步

  • 通过create-react-app创建的react项目,其实是默认已经配置好sass的 需要下载一下依赖
  • 运行以下命令并在文件中创建index.sass文件即可:
npm i sass -S

此时我们重新启动项目即可,创建文件并引入样式即可生效 

配置px转rem自适应 

第一步、

  • 安装lib-flexible、pxtorem 、postcss 命令

npm i lib-flexible postcss-pxtorem postcss postcss-loader postcss-preset-env postcss-flexbugs-fixes -S

第二步、

  • 配置config/webpack.config.js,在config目录下找到webpack.config.js文件,添加如下代码:
// 配置rem
const px2rem = require('postcss-pxtorem');

 第三步、

  • 在128行左右加入如下代码,直接覆盖原本的代码即可:
      {
        // Options for PostCSS as we reference these options twice
        // Adds vendor prefixing based on your specified browser support in
        // package.json
        loader: require.resolve('postcss-loader'),
        options: {
          postcssOptions: {
            // Necessary for external CSS imports to work
            // https://github.com/facebook/create-react-app/issues/2677
            ident: 'postcss',
            config: false,
            plugins: !useTailwind
              ? [
                  'postcss-nested',
                  'postcss-flexbugs-fixes',
                  [
                    'postcss-preset-env',
                    {
                      autoprefixer: {
                        flexbox: 'no-2009',
                      },
                      stage: 3
                    },
                  ],
                  // Adds PostCSS Normalize as the reset css with default options,
                  // so that it honors browserslist config in package.json
                  // which in turn let's users customize the target behavior as per their needs.
                  px2rem({
                    rootValue: 37.5, //设计稿宽/10
                    selectorBlackList  : [], //过滤
                    propList   : ['*'],
                    minPixelValue: 2,
                    exclude: /node_modules/i
                  }), //设计稿根据750px(iphone6)
                'postcss-normalize',
                ]
              : [
                  'tailwindcss',
                  'postcss-flexbugs-fixes',
                  [
                    'postcss-preset-env',
                    {
                      autoprefixer: {
                        flexbox: 'no-2009',
                      },
                      stage: 3,
                    },
                  ],
                  px2rem({
                    rootValue: 37.5,//设计稿宽/10
                    selectorBlackList  : [], //过滤
                    propList   : ['*'],
                    minPixelValue: 2,
                    exclude: /node_modules/i
                    }), //设计稿根据750px(iphone6)
                ],
          },
          sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
        },
      },

 第四步、

  • 在src跟目录下找到index.tsx文件,并在其中加入这行代码
import 'lib-flexible'; 

 第五步、

  • 找到public/ index.html文件 ,在其中加入如下代码
<meta content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport"/>

第六步、

  • 此时我们重新启动项目 npm start :

  •  看到如图中箭头所示处,即代表我们配置成功

配置反向代理和axios

第一步、

  • 安装axios 和 http-proxy-middleware(后面反向代理会用到):
npm i axios http-proxy-middleware -S

第二步、

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

  •  request.ts
//request.ts
 
import axios from "axios";
 
declare module 'axios' {
     export interface AxiosResponse<T = any> extends Promise<T> {}
 }
 
export const Service = axios.create({
  timeout: 3000, //延迟时间
  method: "POST",
  headers: {
    "pc-token": "4a82b23dbbf3b23fd8aa291076e660ec",
    "content-Type": "application/x-www-form-urlencoded",
  },
});
 
//请求拦截
Service.interceptors.request.use((config) => config);
 
//响应拦截
Service.interceptors.response.use(
  (response) => response.data,
  (err) => console.log(err)
);
  • index.ts 
//index.ts
 
import {Service} from './request';
//获取汽车列表
export function getCarList(config: { page: string; }){
    const params = new URLSearchParams()
    params.append('page',config.page);
 
    return Service({
        url:'./api/getCarList',
        data:params
    })
}

第三步、

  • 此时我们需要配置代理,才可以访问到后台的服务器地址
  • 在config文件夹中创建setupProxy.js,内容配置如下

  •  setupProxy.js
const {createProxyMiddleware} = require('http-proxy-middleware');
 
module.exports = function(app) {
  app.use('/api', createProxyMiddleware({ 
    target: 'http://www.ibugthree.com/oldcar/',//后台服务器地址
    changeOrigin: true,
    pathRewrite: {
    '^/api': '',
    },}))
};

第四步、

  • 我们需要对config中paths.js文件修改如下:

proxySetup: resolveApp('config/setupProxy.js'),

第五步、

  • 更改tsconfig.json文件修改如下:

"config/setupProxy.js"
  • 当我们走到这一步时所有的基本都已配置完毕,我们只需要在组件中调用即可:
  • Contact.tsx
import React, { Component } from "react";
//导入要使用的接口
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>
    );
  }
}

第六步、

  • npm start 启动项目查看效果

 配置Redux

第一步、

  • 安装Redux
npm i redux react-redux -S

第二步、

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

第三步、

  • 我们在 action.ts中定义type,然后返回设置状态的type和函数

  •  action.ts
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,
  };
};

第四步、

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

第五步、

  • 在主入口文件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();

第六步、

  • 在App.tsx中我们这样配置
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);

第七步、

  1. 组件中使用redux

  2. 引入connect和action中的方法

  3. 定义props和state类型

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

  5. connect连接属性并导出

  6. About.tsx:

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 className="box">
          <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);
  • 当我们实现如下图所示的效果后就成功了

 配置别名@(选配)

第一步、

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

  • ctrl + f 搜索alias,替换这个alias,代码如下:

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'),
      },

第二步、

  • 此时我们需要注意的是我们每次对ocnfig文件夹的修改,都要重新启动项目

配置antd-mobile(选配)

第一步、

  • 安装antd-mobile ui组件库类似于element-ui
npm install antd-mobile

第二步、

  • 在项目Home.tsx文件中导入我们要使用的组件
  • 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>
    );
  }
}

点击进入antd-module官方地址

总结:

在配置过程中,在控制台中会出现如下问题

 这是基于我们在创建项目是默认将是最新版本的,我们在渲染页面时所使用的方法是ReactDOM

在最新版本中不推荐这样使用

我为大家找到一个文章上面有React版本的一些相关操作

React相关版本操作

至此我们的配置就基本完成,如果有什么问题请及时在评论区告诉我,或有什么高见也可以在评论区发出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值