React 之 airbnb - 项目实战

news2025/1/11 12:36:30

一、开发前言

1. 规范

2. 创建项目 

node -v  => 18.0.0 

npm -v   => 8.6.0

create-react-app star-airbnb

3. 项目基本配置

配置jsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "baseUrl": "./",
    "moduleResolution": "node",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "jsx": "preserve",
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  }
}

通过craco配置

react脚手架隐藏webpack

解决一 : npm run eject 

导出webpack配置,要去找到对应的配置,如果修改错误,项目可能跑不起来

 

解决二 : 通过craco => create-react-app config

配置后,会与原来的webpack配置混合

npm install @craco/craco@alpha -D => "react-scripts": "5.0.1"

新建 craco.config.js文件

/* package.json */
"scripts": {
-   "start": "react-scripts start",
-   "build": "react-scripts build",
-   "test": "react-scripts test",
+   "start": "craco start",
+   "build": "craco build",
+   "test": "craco test",
}
别名
const path = require('path');

const resolve = (pathName) => path.resolve(__dirname, pathName);

module.exports = {
  // webpack
  webpack: {
    alias: {
      '@': resolve('src'),
      'assets': resolve('src/assets'),
      'components': resolve('src/components'),
      'view': resolve('src/view'),
      'store': resolve('src/store'),
      'utils': resolve('src/utils'),
      'router': resolve('src/router'),
      'services': resolve('src/services'),
      'baseUi': resolve('src/base-ui')
    }
  }
};
less文件

可查看 Ant Design 这里所用是4点多的版本

npm i craco-less@2.1.0-alpha.0

const path = require('path');
const resolve = (pathName) => path.resolve(__dirname, pathName);

const CracoLessPlugin = require('craco-less');

module.exports = {
  // less
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            // modifyVars: { '@primary-color': '#1DA57A' },
            javascriptEnabled: true
          }
        }
      }
    }
  ],
  // webpack
  webpack: {
    alias: {
      '@': resolve('src'),
      assets: resolve('src/assets'),
      components: resolve('src/components'),
      view: resolve('src/view'),
      store: resolve('src/store'),
      utils: resolve('src/utils'),
      router: resolve('src/router'),
      services: resolve('src/services'),
      baseUi: resolve('src/base-ui')
    }
  }
};

css样式重置

对默认CSS样式进行重置

normalize.css

npm install normalize.css

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import 'normalize.css';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
reset.css
@mainColor: #484848;

blockquote, body, button, dd, dl, dt, fieldset, form, h1, h2, h3, h4, h5, h6, hr, input, legend, li, ol, p, pre, td, textarea, th, ul {
  // color: @mainColor;
  padding: 0;
  margin: 0;
}

a {
  color: @mainColor;
  text-decoration: none;
}

img {
  vertical-align: top;
}

body {
  font-size: 14px;
  font-family: Circular, "PingFang-SC", "Hiragino Sans GB", "微软雅黑", "Microsoft YaHei", "Heiti SC" ;
  -webkit-font-smoothing: antialiased;
}

目录结构划分

4. 主题配置

项目使用styled-components,可用于配置主题

配置

theme/index.js

export const theme = {
  color: {
    $primaryColor: '#FF385C',
    $secondaryColor: '#00848A',
    $textColor: '#484848',
    $textColorSecondary: '#222222'
  },
  fontSize: {
    $small: '12px',
    $normal: '14px',
    $large: '16px'
  },
  mixin: {
    $boxShadow: `
      transition: box-shadow 0.2s ease;
      &:hover {
        box-shadow: 0 2px 4px rgba(0,0,0,0.18);
      }
    `
  }
};

export default theme;

index.js

import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import { HashRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
// 1. 引入 Provider
import { ThemeProvider } from 'styled-components';

import App from './App';
import store from './store';
import 'normalize.css';
import 'assets/css/index.less';
import { theme } from './theme';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <Provider store={store}>
    {/* 2. 使用主题 */}
    <ThemeProvider theme={theme}>
      <HashRouter>
        <Suspense fallback={<div>Loading...</div>}>
          <App />
        </Suspense>
      </HashRouter>
    </ThemeProvider>
  </Provider>
);

组件使用

import styled from 'styled-components';

export const LeftWrapper = styled.div.attrs((props) => ({
  // 1. 使用主题, 通过 props.theme 获取主题
  $primaryColor: props.theme.color.$primaryColor,
  $secondaryColor: props.theme.color.$secondaryColor
}))`
  flex: 1;
  display: flex;
  align-items: center;
  /* 2. 使用,这里是用一个回调函数 */
  color: ${({ $primaryColor }) => $primaryColor};
  .log {
    cursor: pointer;
  }
`;

5. 路由配置

npm install react-router-dom

router/index.js

import React, { lazy } from 'react';
import { Navigate } from 'react-router-dom';

const Home = lazy(() => import('view/home'));
const Entire = lazy(() => import('view/entire'));
const Detail = lazy(() => import('view/detail'));

const routes = [
  {
    path: '/',
    element: <Navigate to='/home' />
  },
  {
    path: '/home',
    element: <Home />
  },
  {
    path: '/entire',
    element: <Entire />
  },
  {
    path: '/detail',
    element: <Detail />
  }
];

export default routes;

index.js

import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import { HashRouter } from 'react-router-dom';

import App from './App';
import 'normalize.css';
import 'assets/css/index.less';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <HashRouter>
      <Suspense fallback={<div>Loading...</div>}>
        <App />
      </Suspense>
    </HashRouter>
  </React.StrictMode>
);

App.jsx

import React, { memo } from 'react';
import { useRoutes } from 'react-router-dom';

import routes from 'router';

const App = memo(() => {
  return (
    <>
      <div className='header'>header</div>
      <div className='main-contain'>{useRoutes(routes)}</div>
      <div className='footer'>footer</div>
    </>
  );
});

export default App;

6. redux状态管理配置

npm install @reduxjs/toolkit react-redux

store

modules
home.js

home.js => 使用rtk模式

import { createSlice } from '@reduxjs/toolkit';

const homeSlice = createSlice({
  name: 'home',
  initialState: {
    a: [1, 2, 3, 4]
  },
  reducers: {}
});

export default homeSlice.reducer;
entire文件夹 

entire => 使用原生模式,所以有四个文件

reducer.js
const initialState = {
  b: [1, 2, 3, 4]
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    // case 'ADD_USER':
    //   return {
    //     ...state,
    //     [action.payload.id]: action.payload
    //   };
    default:
      return state;
  }
};

export default reducer;
index.js
import reducer from './reducer';

export default reducer;
index.js
import { configureStore } from '@reduxjs/toolkit';
import homeReducer from './modules/home';
// 直接使用原生的entire,也是一样的,因为createSlice就是对原生的一种封装而已
import entireReducer from './modules/entire';

const store = configureStore({
  reducer: {
    home: homeReducer,
    entire: entireReducer
  }
});

export default store;

index.js 

import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import { HashRouter } from 'react-router-dom';

import { Provider } from 'react-redux';
import App from './App';
import store from './store';
import 'normalize.css';
import 'assets/css/index.less';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <HashRouter>
        <Suspense fallback={<div>Loading...</div>}>
          <App />
        </Suspense>
      </HashRouter>
    </Provider>
  </React.StrictMode>
);

7. 网络请求 - axios配置

npm install axios

requset

config.js
export const BASE_URL = 'http://xxxxxx';
export const TIME_OUT = 20000;
index.js
import axios from 'axios';
import { BASE_URL, TIME_OUT } from './config';

class StarRequest {
  constructor(baseURL, timeout) {
    this.instance = axios.create({
      baseURL,
      timeout
    });

    this.instance.interceptors.response.use(
      (res) => {
        return res.data;
      },
      (err) => {
        return err;
      }
    );
  }
  request(config) {
    return this.instance(config);
  }
  get(config) {
    return this.request({ ...config, method: 'get' });
  }
  post(config) {
    return this.request({ ...config, method: 'post' });
  }
}

const starRequest = new StarRequest(BASE_URL, TIME_OUT);
export default starRequest;

index.js 

import starRequest from './request';

export default starRequest;

简单使用

import React, { memo, useEffect, useState } from 'react';
import starRequest from '@/services';

const Home = memo(() => {
  // 定义状态
  const [highscore, sethighscore] = useState({});
  // 请求
  useEffect(() => {
    starRequest.get({ url: '/home/highscore' }).then((res) => {
      console.log(res);
      sethighscore(res);
    });
  }, []);
  return (
    <>
      <div>Home</div>
      <div>{highscore.title}</div>
    </>
  );
});

export default Home;

二、注意事项

图片问题

导入需使用import | require 导入方可使用

不论是背景图片还是img使用图片

import导入

import styled from 'styled-components';
import coverPic from '@/assets/img/cover_01.jpeg';

export const BannerWrapper = styled.div`
  height: 529px;
  background: url(${coverPic}) center center/cover;
`;

require导入

import styled from 'styled-components';

export const BannerWrapper = styled.div`
  height: 529px;
  background: url(${require('@/assets/img/cover_01.jpeg')}) center center/cover;
  
  /* 根据webpack版本不同,可能需要加default */
  /* background: url(${require('@/assets/img/cover_01.jpeg').default}) center center/cover; */
`;

三、引入组件库

Material-Ui

安装

npm install @mui/material @mui/styled-engine-sc

配置

const path = require('path');
const resolve = (pathName) => path.resolve(__dirname, pathName);

const CracoLessPlugin = require('craco-less');

module.exports = {
  // less
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            // modifyVars: { '@primary-color': '#1DA57A' },
            javascriptEnabled: true
          }
        }
      }
    }
  ],
  // webpack
  webpack: {
    alias: {
      '@': resolve('src'),
      assets: resolve('src/assets'),
      components: resolve('src/components'),
      view: resolve('src/view'),
      store: resolve('src/store'),
      utils: resolve('src/utils'),
      router: resolve('src/router'),
      services: resolve('src/services'),
      baseUi: resolve('src/base-ui'),
      // ++++++++++++++++
      '@mui/styled-engine': '@mui/styled-engine-sc'
    }
  }
};

Ant-Design

安装

npm install antd

使用

// 直接组件中使用即可

import { Button } from 'antd';

<Button type='primary'>Button</Button>

四、项目效果

小视频

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1265007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何设置带有密码的excel只读模式?

Excel只读模式大家都不陌生&#xff0c;那大家知道带有密码的只读模式吗&#xff1f;今天给大家分享如何设置带有密码的只读模式。 打开excel文件&#xff0c;将文件进行【另存为】设置&#xff0c;然后停留在保存路径的界面中&#xff0c;我们点击下面的工具 – 常规选项 在常…

postgresql以及postgis安装

一、安装postgresql及postgis 1.下载postgresql https://www.enterprisedb.com/downloads/postgres-postgresql-downloads 我选择的版本为“postgresql-14.8-2-windows-x64.exe”。 2.以管理员模式运行安装程序 安装路径建议不要C盘&#xff0c;可能会由于权限问题导致目录…

【计算机毕业设计】nodejs+vue音乐播放器系统 微信小程序83g3s

本系统的设计与实现共包含12个表:分别是配置文件信息表&#xff0c;音乐列表评论表信息表&#xff0c;音乐论坛信息表&#xff0c;歌手介绍信息表&#xff0c;音乐资讯信息表&#xff0c;收藏表信息表&#xff0c;token表信息表&#xff0c;用户表信息表&#xff0c;音乐类型信…

Elasticsearch:向量搜索 (kNN) 实施指南 - API 版

作者&#xff1a;Jeff Vestal 本指南重点介绍通过 HTTP 或 Python 使用 Elasticsearch API 设置 Elasticsearch 以进行近似 k 最近邻 (kNN) 搜索。 对于主要使用 Kibana 或希望通过 UI 进行测试的用户&#xff0c;请访问使用 Elastic 爬虫的语义搜索入门指南。你也可以参考文章…

最新AIGC创作系统ChatGPT系统源码+DALL-E3文生图+图片上传对话识图/支持OpenAI-GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI…

Java实现通过经纬度求两个任意地点在球面上的距离

我们在实际开发中会获取对应的经纬度&#xff0c;可以使用ES大数据搜索引擎进行计算对应区域的数据&#xff0c;那我们在如何根据两个经纬度获取对应的球面距离&#xff0c;就是在地球上从一个地点到另一个地点的直线距离 工具类如下: public class GeoUtils {// 地球半径&am…

手把手教你如何实现List——ArrayList

目录 前言&#xff1a; 线性表 顺序表 接口的实现 一. 打印顺序表 二.新增元素,默认在数组最后新增 三.在 pos 位置新增元素 四.判定是否包含某个元素 五. 查找某个元素对应的位置 六.获取 pos 位置的元素 七.给 pos 位置的元素设为 value 八.删除第一次出现的关键字k…

移动应用开发介绍及iOS方向学习路线(HUT移动组版)

移动应用开发介绍及iOS方向学习路线&#xff08;HUT移动组版&#xff09; 前言 ​ 作为一个HUT移动组待了一坤年&#xff08;两年半&#xff09;多的老人&#xff0c;在这里为还在考虑进哪个组的萌新们以及将来进组的新朋友提供一份关于移动应用开发介绍以及学习路线的白话文…

华为云(HECS)docker环境下安装jenkins

Jenkins是一个开源的自动化工具&#xff0c;可以自动化地完成构建、测试、交付或部署等任务。总之重点就是三个字&#xff1a;自动化&#xff0c;至于如何实现这些功能&#xff0c;Jenkins基于插件化的机制&#xff0c;提供了众多的插件来完成持续集成CI与持续部署CD。 【持续…

直播场景视频和特效解决方案

直播已经成为企业与消费者互动的重要方式&#xff0c;如何提供优质的直播内容&#xff0c;提升直播效果&#xff0c;以及实现直播内容的商业化转化&#xff0c;一直是企业面临的重要挑战。为此&#xff0c;美摄科技提供了一套全面的直播场景解决方案&#xff0c;帮助企业解决这…

内网渗透(哈希传递)

概念 早期SMB协议明文在网络上传输数据&#xff0c;后来诞生了LM验证机制&#xff0c;LM机制由于过于简单&#xff0c;微软提出了WindowsNT挑战/响应机制&#xff0c;这就是NTLM。 哈希传递前提 同密码(攻击主机与实现主机两台要密码一致)。 NTLM协议 加密ntlm哈希 转换成…

力扣hot100 最大子数组和 动态规划 分治 无后效性 子问题划分

&#x1f468;‍&#x1f3eb; 题目地址 无后效性 为了保证计算子问题能够按照顺序、不重复地进行&#xff0c;动态规划要求已经求解的子问题不受后续阶段的影响。这个条件也被叫做「无后效性」。换言之&#xff0c;动态规划对状态空间的遍历构成一张有向无环图&#xff0c;遍…

UE4 UE5 使用SVN控制

关键概念&#xff1a;虚幻引擎中使用SVN&#xff0c;帮助团队成员共享资源。 1. UE4/UE5项目文件 如果不需要编译的中间缓存&#xff0c;则删除&#xff1a; DerivedDataCache、Intermediate、Saved 三个文件夹 2.更新、上传

梦极光(ez_re???)

ez_re 先查壳看看&#xff0c;没有壳 32位 我先说说这道题 打开分析找到主函数 在这里就是flag了&#xff0c;用十六进制转ascll码 我们先运行这个程序看看 我想说说我的想法 首先没看出来这里是十六进制转ascll码其次41D538数组用来干啥来的&#xff1f;题目里面给出的请…

JVM GC算法

一, 垃圾回收分类: 按线程数分&#xff0c;可以分为串行垃圾回收器和并行垃圾回收器。 按工作模式分&#xff0c;可以分为并发垃圾回收器和独占式垃圾回收器 按碎片处理方式分&#xff0c;可以分为压缩式垃圾回收器和非压缩式垃圾回收器按工作的内存区间分&#xff0c;又可分为…

Linux常用命令----shutdown命令

文章目录 命令概述参数解释使用示例及解释 命令概述 shutdown 命令用于安全地关闭或重启 Linux 系统。它允许管理员指定一个时间点执行操作&#xff0c;并可发送警告信息给所有登录的用户。 参数解释 时间参数 ([时间]): now: 立即执行关闭或重启操作。m: 在 m 分钟后执行操作…

redis基本数据结构

Redis入门&#xff1a;五大数据类型 文章目录 Redis入门&#xff1a;五大数据类型一.概述二.Redis的基本了解三.Redis五大数据类型1.String (字符串)2.List(列表)3.Set集合(元素唯一不重复)4.Hash集合5.zSet(有序集合) 一.概述 什么是Redis Redis&#xff08;Remote Dictiona…

【好用的个人工具】在Docker环境下部署Simple mind map思维导图工具

【好用的个人工具】在Docker环境下部署Simple mind map思维导图工具 一、Simple mind map介绍1.1 Simple mind map简介1.2 Simple mind map特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker co…

基于STM32 + TIM _定时器的基本机构和工作原理详解

前言 本篇博客主要学习了解定时器的基本结构和工作原理&#xff0c;掌握定时器的驱动程序和设计。本篇博客大部分是自己收集和整理&#xff0c;如有侵权请联系我删除。 本次博客板子使用的是正点原子精英版&#xff0c;芯片是STM32F103ZET6,需要资料可以我拿取。 本博客内容原…

线性系统理论 -- 降阶观测器的设计

定理&#xff1a; 若系统能观测&#xff0c;且rankCm&#xff0c;则系统的状态观测器的最小维数是(n-m)。 线性定常时不变系统方程如下&#xff08;以三阶(n3)单入单出系统为例&#xff0c;有mrankC1&#xff09;&#xff1a; 取变换阵P&#xff0c;有&#xff1a; 对上述系统…