程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

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

发布于2022-03-19 01:50     阅读(2081)     评论(0)     点赞(23)     收藏(3)


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

npx create-react-app testproject --template typescript

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

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

npm run 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:

  1. import React, { Component } from "react";
  2. export default class Home extends Component {
  3. render() {
  4. return (
  5. <div className="home">
  6. <div className="container">
  7. <h3 className="center"> Home页面</h3>
  8. <p>欢迎来到首页</p>
  9. </div>
  10. </div>
  11. );
  12. }
  13. }

Contact:

  1. import React, { Component } from "react";
  2. export default class Contact extends Component {
  3. render() {
  4. return (
  5. <div className="contact">
  6. <div className="container">
  7. <h3 className="center"> Contact页面</h3>
  8. <p>欢迎来到联系我们页面!</p>
  9. </div>
  10. </div>
  11. );
  12. }
  13. }

About:

  1. import React, { Component } from "react";
  2. export default class About extends Component {
  3. render() {
  4. return (
  5. <div className="about">
  6. <div className="container">
  7. <h3 className="center"> About页面</h3>
  8. <p>欢迎来到关于我们页面!</p>
  9. </div>
  10. </div>
  11. );
  12. }
  13. }

Navbar:

  1. import React, { Component } from "react";
  2. export default class Navbar extends Component {
  3. render() {
  4. return (
  5. <nav className="nav-wrapper">
  6. <div className="list">
  7. <ul>
  8. <li><a href='/'>Home</a></li>
  9. <li><a href='/about'>About</a></li>
  10. <li><a href='/contact'>Contact</a></li>
  11. </ul>
  12. </div>
  13. </nav>
  14. )
  15. }
  16. }

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

  1. // 导入路由组件
  2. import Home from '../views/Home'
  3. import About from '../views/About'
  4. import Contact from '../views/Contact'
  5. // 导入路由管理工具
  6. import {RouteConfig} from 'react-router-config'
  7. const routes:RouteConfig = [
  8. {
  9. path:'/',
  10. exact:true,
  11. component:Home
  12. },
  13. {
  14. path:'/about',
  15. exact:true,
  16. component:About
  17. },
  18. {
  19. path:'/contact',
  20. exact:true,
  21. component:Contact
  22. }
  23. ]
  24. export default routes;

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

  1. import React from "react";
  2. // 引入路由导航栏
  3. import Navbar from "./views/Navbar";
  4. // 引入routes组件
  5. import routes from "./routes";
  6. // 引入包管理工具
  7. import { renderRoutes, RouteConfig } from "react-router-config";
  8. import "./App.css";
  9. function App() {
  10. return (
  11. <div className="App">
  12. <Navbar />
  13. {/* 设置routes的类型为RouteConfig[],否则报错 */}
  14. {renderRoutes(routes as RouteConfig[])}
  15. </div>
  16. );
  17. }
  18. export default App;

根目录index.tsx中这样定义

  1. import React from "react";
  2. import ReactDOM from "react-dom";
  3. import "./index.css";
  4. import App from "./App";
  5. import reportWebVitals from "./reportWebVitals";
  6. import { BrowserRouter as Router } from "react-router-dom";
  7. ReactDOM.render(
  8. <React.StrictMode>
  9. <Router>
  10. <App />
  11. </Router>
  12. </React.StrictMode>,
  13. document.getElementById("root")
  14. );
  15. // If you want to start measuring performance in your app, pass a function
  16. // to log results (for example: reportWebVitals(console.log))
  17. // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
  18. reportWebVitals();

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

 运行命令

npm i react-router@5.2.0 -s

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

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

  1. * {
  2. padding: 0;
  3. margin: 0;
  4. }
  5. h1 {
  6. text-align: center;
  7. font-size: 45px;
  8. font-family: Arial, Helvetica, sans-serif;
  9. color: rgb(6, 0, 32);
  10. padding: 40px;
  11. }
  12. .list {
  13. display: flex;
  14. justify-content: center;
  15. width: 100%;
  16. }
  17. .list ul li {
  18. list-style: none;
  19. margin: 42px;
  20. text-align: center;
  21. }
  22. a {
  23. text-decoration: none;
  24. color: rgb(0, 0, 0);
  25. font-size: 18px;
  26. font-family: Arial, Helvetica, sans-serif;
  27. padding: 14px 25px;
  28. background-color: transparent;
  29. border: 2px solid rgb(12, 0, 66);
  30. }
  31. a:hover {
  32. background-color: rgb(12, 0, 66);
  33. color: rgb(255, 255, 255);
  34. }

三、配置less

 第一种方式:暴露配置的方式

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,在此处添加

 

  1. // less
  2. const lessRegex = /\.less$/;
  3. const lessModuleRegex = /\.module\.less$/;

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

  1. // less
  2. {
  3. test: lessRegex,
  4. exclude: lessModuleRegex,
  5. use: getStyleLoaders(
  6. {
  7. importLoaders: 2,
  8. sourceMap: isEnvProduction && shouldUseSourceMap,
  9. },
  10. 'less-loader'
  11. ),
  12. sideEffects: true,
  13. },
  14. // less
  15. {
  16. test: lessModuleRegex,
  17. use: getStyleLoaders(
  18. {
  19. importLoaders: 2,
  20. sourceMap: isEnvProduction && shouldUseSourceMap,
  21. modules: true,
  22. getLocalIdent: getCSSModuleLocalIdent,
  23. },
  24. 'less-loader'
  25. ),
  26. },

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

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

这种方式有个不好的地方,就是会产生很多不必要的js文件,且这个操作不可逆,等到后期项目上传时造成代码冗余,不好维护。

第二种方式:找到config.js文件直接修改

1.找到文件路径:node_modules\react-scripts\config\webpack.config.js

 2.在60-80行之间有个cssRegex,在此处添加

  1. // less
  2. const lessRegex = /\.less$/;
  3. const lessModuleRegex = /\.module\.less$/;

3. 在550多行有个sassRegex,模仿写对应的lessRegex

  1. // less
  2. {
  3. test: lessRegex,
  4. exclude: lessModuleRegex,
  5. use: getStyleLoaders(
  6. {
  7. importLoaders: 2,
  8. sourceMap: isEnvProduction && shouldUseSourceMap,
  9. },
  10. "less-loader"
  11. ),
  12. sideEffects: true,
  13. },
  14. // less
  15. {
  16. test: lessModuleRegex,
  17. use: getStyleLoaders(
  18. {
  19. importLoaders: 2,
  20. sourceMap: isEnvProduction && shouldUseSourceMap,
  21. modules: true,
  22. getLocalIdent: getCSSModuleLocalIdent,
  23. },
  24. "less-loader"
  25. ),
  26. },

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

  1. .about{
  2. .container{
  3. font-size: 22px;
  4. p{
  5. color: red;
  6. }
  7. }
  8. }

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

四、配置sass

通过create-react-app创建的react项目,其实是默认已经配置好sass的,所以我们先尝试在项目中引入sass文件

会发生如下报错:

解决方法:执行下面的命令

npm i sass -s

 然后重新运行即可,样式生效

五、配置px2rem自适应

第一种方式:暴露config

1. 安装lib-flexible、pxtorem,postcss

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

2.配置config/webpack.config.js,在config目录下找到webpack.config.js文件,加入

const px2rem = require('postcss-pxtorem');

3. 然后再下面代码中加入下面这行

  1. px2rem({
  2. rootValue: 75,
  3. propWhiteList: [],
  4. minPixelValue: 2,
  5. exclude: /node_modules/i,
  6. unitPrecision: 5,
  7. propList: ['*']
  8. }), //设计稿根据750px(iphone6)

 也可以使用一下代码覆盖loader

  1. {
  2. // Options for PostCSS as we reference these options twice
  3. // Adds vendor prefixing based on your specified browser support in
  4. // package.json
  5. loader: require.resolve('postcss-loader'),
  6. options: {
  7. postcssOptions: {
  8. // Necessary for external CSS imports to work
  9. // https://github.com/facebook/create-react-app/issues/2677
  10. ident: 'postcss',
  11. config: false,
  12. plugins: !useTailwind
  13. ? [
  14. 'postcss-nested',
  15. 'postcss-flexbugs-fixes',
  16. [
  17. 'postcss-preset-env',
  18. {
  19. autoprefixer: {
  20. flexbox: 'no-2009',
  21. },
  22. stage: 3
  23. },
  24. ],
  25. // Adds PostCSS Normalize as the reset css with default options,
  26. // so that it honors browserslist config in package.json
  27. // which in turn let's users customize the target behavior as per their needs.
  28. px2rem({
  29. rootValue: 37.5,
  30. selectorBlackList : [], //过滤
  31. propList : ['*'],
  32. minPixelValue: 2,
  33. exclude: /node_modules/i
  34. }), //设计稿根据750px(iphone6)
  35. 'postcss-normalize',
  36. ]
  37. : [
  38. 'tailwindcss',
  39. 'postcss-flexbugs-fixes',
  40. [
  41. 'postcss-preset-env',
  42. {
  43. autoprefixer: {
  44. flexbox: 'no-2009',
  45. },
  46. stage: 3,
  47. },
  48. ],
  49. px2rem({
  50. rootValue: 37.5,
  51. selectorBlackList : [], //过滤
  52. propList : ['*'],
  53. minPixelValue: 2,
  54. exclude: /node_modules/i
  55. }), //设计稿根据750px(iphone6)
  56. ],
  57. },
  58. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
  59. },
  60. },

4. src目录下找到index入口文件,在文件上面加入

import 'lib-flexible'


5. 找到public/index.html文件,加入如下代码:

  1. <meta content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"
  2.         name="viewport"/>


6. 重新运行项目,一般就可以看到px转rem了。

  1. .contact {
  2. .container {
  3. font-size: 36px;
  4. .center {
  5. color: blue;
  6. }
  7. p {
  8. font-size: 24px;
  9. }
  10. button {
  11. width: 100px;
  12. height: 45px;
  13. background: #ccc;
  14. color: #fff;
  15. }
  16. }
  17. }

 第二种方式:直接在config文件中修改

1.找到文件路径:node_modules\react-scripts\config\webpack.config.js

 2.配置webpack.config.js,加入如下代码:

const px2rem = require('postcss-pxtorem');

3. 然后再下面代码中加入下面这行

  1. px2rem({
  2. rootValue: 75,
  3. propWhiteList: [],
  4. minPixelValue: 2,
  5. exclude: /node_modules/i,
  6. unitPrecision: 5,
  7. propList: ['*']
  8. }), //设计稿根据750px(iphone6)

也可以使用一下代码覆盖loader

  1. {
  2. // Options for PostCSS as we reference these options twice
  3. // Adds vendor prefixing based on your specified browser support in
  4. // package.json
  5. loader: require.resolve('postcss-loader'),
  6. options: {
  7. postcssOptions: {
  8. // Necessary for external CSS imports to work
  9. // https://github.com/facebook/create-react-app/issues/2677
  10. ident: 'postcss',
  11. config: false,
  12. plugins: !useTailwind
  13. ? [
  14. 'postcss-nested',
  15. 'postcss-flexbugs-fixes',
  16. [
  17. 'postcss-preset-env',
  18. {
  19. autoprefixer: {
  20. flexbox: 'no-2009',
  21. },
  22. stage: 3
  23. },
  24. ],
  25. // Adds PostCSS Normalize as the reset css with default options,
  26. // so that it honors browserslist config in package.json
  27. // which in turn let's users customize the target behavior as per their needs.
  28. px2rem({
  29. rootValue: 37.5,
  30. selectorBlackList : [], //过滤
  31. propList : ['*'],
  32. minPixelValue: 2,
  33. exclude: /node_modules/i
  34. }), //设计稿根据750px(iphone6)
  35. 'postcss-normalize',
  36. ]
  37. : [
  38. 'tailwindcss',
  39. 'postcss-flexbugs-fixes',
  40. [
  41. 'postcss-preset-env',
  42. {
  43. autoprefixer: {
  44. flexbox: 'no-2009',
  45. },
  46. stage: 3,
  47. },
  48. ],
  49. px2rem({
  50. rootValue: 37.5,
  51. selectorBlackList : [], //过滤
  52. propList : ['*'],
  53. minPixelValue: 2,
  54. exclude: /node_modules/i
  55. }), //设计稿根据750px(iphone6)
  56. ],
  57. },
  58. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
  59. },
  60. },

4. src目录下找到index入口文件,在文件上面加入

import 'lib-flexible'

 
5. 找到public/index.html文件,加入如下代码:

  1. <meta content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"
  2.         name="viewport"/>


6. 重新运行项目,一般就可以看到px转rem了。

存在问题:当设备宽度超过540后,样式就固定在540不再改变了

解决方法:在node-modules => lib-flexible => flexible.js中找到refreshRem修改其中的width值为设计稿宽度即可

六、配置axios和反向代理

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

npm i axios http-proxy-middleware -s

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

  1. //index.ts
  2. import {Service} from './request';
  3. //获取汽车列表
  4. export function getCarList(config: { page: string; }){
  5. const params = new URLSearchParams()
  6. params.append('page',config.page);
  7. return Service({
  8. url:'./api/getCarList',
  9. data:params
  10. })
  11. }
  12. //request.ts
  13. import axios from "axios";
  14. declare module 'axios' {
  15. export interface AxiosResponse<T = any> extends Promise<T> {}
  16. }
  17. export const Service = axios.create({
  18. timeout: 3000, //延迟时间
  19. method: "POST",
  20. headers: {
  21. "pc-token": "4a82b23dbbf3b23fd8aa291076e660ec",
  22. "content-Type": "application/x-www-form-urlencoded",
  23. },
  24. });
  25. //请求拦截
  26. Service.interceptors.request.use((config) => config);
  27. //响应拦截
  28. Service.interceptors.response.use(
  29. (response) => response.data,
  30. (err) => console.log(err)
  31. );

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

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

  1. const {createProxyMiddleware} = require('http-proxy-middleware');
  2. module.exports = function(app) {
  3. app.use('/api', createProxyMiddleware({
  4. target: 'http://www.ibugthree.com/oldcar/',//后台服务器地址
  5. changeOrigin: true,
  6. pathRewrite: {
  7. '^/api': '',
  8. },}))
  9. };

在新版本中已经默认设置代理的文件夹名为setupProxy.js

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

  1. import React, { Component } from "react";
  2. import "./contact.scss";
  3. //导入要使用的接口
  4. import { getCarList } from "../api/index";
  5. export default class Contact extends Component {
  6. // 定义方法
  7. getList() {
  8. getCarList({ page: "1" }).then((res) => console.log(res));
  9. }
  10. render() {
  11. return (
  12. <div className="contact">
  13. <div className="container">
  14. <h3 className="center"> Contact页面</h3>
  15. <p>欢迎来到联系我们页面!</p>
  16. {/* 点击事件调用 */}
  17. <button onClick={this.getList}>获取数据</button>
  18. </div>
  19. </div>
  20. );
  21. }
  22. }

 

 七、配置redux

1. 安装redux

npm i redux react-redux -s

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

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

  1. export const SET_AGE = "set_age";
  2. export const SET_NAME = "set_name";
  3. export const setAge = function (n: number) {
  4. return {
  5. type: SET_AGE,
  6. n: n,
  7. };
  8. };
  9. export const setName = function (name: string) {
  10. return {
  11. type: SET_NAME,
  12. name: name,
  13. };
  14. };

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

  1. import { createStore } from "redux";
  2. import { SET_AGE, SET_NAME } from "./action";
  3. interface User {
  4. name: string;
  5. age: number;
  6. }
  7. const common: User = {
  8. name: "张三123",
  9. age: 18,
  10. };
  11. function user(state = common, action: any) {
  12. switch (action.type) {
  13. case SET_AGE:
  14. return {
  15. ...state,
  16. age: state.age + action.n,
  17. };
  18. case SET_NAME:
  19. return {
  20. ...state,
  21. name: action.name,
  22. };
  23. default:
  24. return state;
  25. }
  26. }
  27. export default createStore(user);

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

  1. import React from "react";
  2. import ReactDOM from "react-dom";
  3. import "./index.css";
  4. import App from "./App";
  5. import reportWebVitals from "./reportWebVitals";
  6. // 引入路由组件
  7. import { BrowserRouter as Router } from "react-router-dom";
  8. // 引入移动端自适应
  9. import "lib-flexible";
  10. //引入rootReducer组件
  11. import { Provider } from "react-redux";
  12. import store from "./store";
  13. ReactDOM.render(
  14. <React.StrictMode>
  15. {/* provider组件将所有的组件包裹起来,用绑定属性的形式绑定store到组件中 */}
  16. <Provider store={store}>
  17. <Router>
  18. <App />
  19. </Router>
  20. </Provider>
  21. </React.StrictMode>,
  22. document.getElementById("root")
  23. );
  24. reportWebVitals();

4. 在App中进行配置

  1. import React from "react";
  2. // 引入路由导航栏
  3. import Navbar from "./views/Navbar";
  4. // 引入routes组件
  5. import routes from "./routes";
  6. // 引入包管理工具
  7. import { renderRoutes, RouteConfig } from "react-router-config";
  8. import "./App.css";
  9. // 引入connect连接组件
  10. import {connect} from "react-redux"
  11. function App() {
  12. return (
  13. <div className="App">
  14. <Navbar />
  15. {/* 设置routes的类型为RouteConfig[],否则报错 */}
  16. {renderRoutes(routes as RouteConfig[])}
  17. </div>
  18. );
  19. }
  20. //进行连接
  21. export default connect((props,state)=>Object.assign({},props,state),{})(App);

5.组件中使用redux

    1. 引入connect和action中的方法

    2. 定义props和state类型

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

    4. connect连接属性并导出

  1. import React, { Component } from "react";
  2. import "./about.less";
  3. // redux
  4. import { connect } from "react-redux";
  5. import { setName, setAge } from "../store/action";
  6. interface Props {
  7. setAge: Function;
  8. setName: Function;
  9. age: number;
  10. name: string;
  11. }
  12. interface State {}
  13. class About extends Component<Props,State> {
  14. refs:any = React.createRef()
  15. // eslint-disable-next-line @typescript-eslint/no-useless-constructor
  16. constructor(props:Props){
  17. super(props)
  18. }
  19. changeAge(){
  20. this.props.setAge(1);
  21. console.log(this.props);
  22. }
  23. changeName(){
  24. let name:number = this.refs.value
  25. this.props.setName(name)
  26. console.log(this.refs);
  27. this.refs.value = ''
  28. }
  29. render() {
  30. return (
  31. <div className="about">
  32. <div className="container">
  33. <h3 className="center"> About页面</h3>
  34. <p>欢迎来到关于我们页面!</p>
  35. </div>
  36. <div>
  37. <p>名字是:{this.props.name}</p>
  38. <input ref={(input: HTMLInputElement) => this.refs = input} type="text" />
  39. <button onClick={this.changeName.bind(this)}>修改姓名</button>
  40. <p>年龄是:{this.props.age}</p>
  41. <button onClick={this.changeAge.bind(this)}>修改年龄</button>
  42. </div>
  43. </div>
  44. );
  45. }
  46. }
  47. export default connect((props,state)=>Object.assign({},props,state),{
  48. setAge,setName
  49. })(About);

八、配置别名@

一、暴露方法

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

 2.搜索 alias

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

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

二、直接在config文件中修改

1.找到文件路径:node_modules\react-scripts\config\webpack.config.js

其他步骤同上!!

需要特别注意的是: webpack配置进行改动后,都需要重新启动项目,不然不生效

九、配置antd-mobile

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

  1. npm install antd-mobile
  2. //或
  3. yarn add antd-mobile

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

  1. import React, { Component } from "react";
  2. //使用组件直接在组件中进行使用即可
  3. import { Button } from 'antd-mobile';
  4. export default class Home extends Component {
  5. render() {
  6. return (
  7. <div className="home">
  8. <div className="container">
  9. <h3 className="center"> Home页面</h3>
  10. <p>欢迎来到首页</p>
  11. <Button color='primary'>按钮</Button>
  12. </div>
  13. </div>
  14. );
  15. }
  16. }

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

至此,react项目创建和配置完成

如有问题,请及时沟通

原文链接:https://blog.csdn.net/weixin_42582523/article/details/121791925




所属网站分类: 技术文章 > 博客

作者:听说你混的不错

链接:http://www.qianduanheidong.com/blog/article/318962/f58b0af72068892078b7/

来源:前端黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

23 0
收藏该文
已收藏

评论内容:(最多支持255个字符)