React 之 airbnb - 项目实战

一、开发前言

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>

四、项目效果

小视频

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言——求π的近似值

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> #include<math.h> int main() {int s;double n,t,pi;t1;pi0;n1.0;s1;while (fabs(t)>1e-6){pipit; nn2; s-s; ts/n;}pipi*4;printf("pi%lf\n",pi);return 0; }这里是求小数点后6位——1e-6&#…

灰度发布专题---3、Nginx+Lua灰度发布

上一章已经讲解了配置文件灰度发布、应用版本灰度发布、API网关灰度发布实现&#xff0c;但如果用户这时候在代理层如何做灰度发布呢&#xff1f; 代理层灰度发布分析 用户无论访问应用服务还是静态页&#xff0c;都要经过Nginx代理层&#xff0c;我们可以在Nginx这里做灰度发…

哈希表——闭散列表

该哈希表实现是闭散列实现法。 闭散列表&#xff1a; 闭散列&#xff1a;也叫开放定址法&#xff0c;当发生哈希冲突时&#xff0c;如果哈希表未被装满&#xff0c;说明在哈希表中必然还有空位置&#xff0c;那么可以把key存放到冲突位置中的“下一个” 空位置中去。 那如何寻…

【傻瓜级JS-DLL-WINCC-PLC交互】3.JS-DLL进行交互

思路 JS-DLL-WINCC-PLC之间进行交互&#xff0c;思路&#xff0c;先用Visual Studio创建一个C#的DLL控件&#xff0c;然后这个控件里面嵌入浏览器组件&#xff0c;实现JS与DLL通信&#xff0c;然后DLL放入到WINCC里面的图形编辑器中&#xff0c;实现DLL与WINCC的通信。然后PLC与…

万宾科技可燃气体监测仪科技作用全览

燃气管网在运行过程中经常会遇到燃气管道泄漏的问题&#xff0c;燃气泄漏甚至会引起爆炸&#xff0c;从而威胁人民的生命和财产安全&#xff0c;因此对燃气管网进行定期巡检是十分必要的工作。但是传统的人工巡检已不能满足城市的需要&#xff0c;除了选择增加巡检人员之外&…

SELinux(一) 简介

首发公号&#xff1a;Rand_cs 前段时间的工作遇到了一些关于 SELinux 的问题&#xff0c;初次接触不熟悉此概念&#xff0c;导致当时配置策略时束手束脚&#xff0c;焦头烂额&#xff0c;为此去系统的学习了下 SELinux 的东西。聊 SELinux 之前&#xff0c;先来看看什么叫做访…

Mac电脑音乐标签管理 Yate 激活最新 for Mac

Yate是一款非常实用的音频编辑和标记软件&#xff0c;它提供了丰富的功能和工具来帮助用户编辑、整理和管理音频文件。无论是在音乐收藏管理、DJ和音乐制作方面&#xff0c;还是在其他需要处理大量音频文件的领域&#xff0c;Yate都是非常值得推荐的工具。 Yate for Mac功能特…

2023网络安全产业图谱

1. 前言 2023年7月10日&#xff0c;嘶吼安全产业研究院联合国家网络安全产业园区&#xff08;通州园&#xff09;正式发布《嘶吼2023网络安全产业图谱》。 嘶吼安全产业研究院根据当前网络安全发展规划与趋势发布《嘶吼2023网络安全产业图谱》调研&#xff0c;旨在进一步了解…

【力扣】189. 轮转数组

【力扣】189. 轮转数组 文章目录 【力扣】189. 轮转数组1. 题目介绍2. 解法2.1 方法一&#xff1a;不太正规&#xff0c;但是简单2.2 方法二&#xff1a;使用额外的数组2.3 方法三&#xff1a;环状替换2.4 方法四&#xff1a;数组翻转 3. Danger参考 1. 题目介绍 给定一个整数…

使用mock.js模拟数据

一、安装mock.js npm i mockjs 二、配置JSON文件 我们创建一个mock文件夹&#xff0c;用于存放mock相关的模拟数据和代码实现。 我们将数据全部放在xxx.json文件夹下&#xff0c;里面配置我们需要的JSON格式的数据。 注意&#xff1a;json文件中不要留有空格&#xff0c;否则…

八股文-如何理解Java中的多态

什么是多态&#xff1f; 多态是面向对象编程的一个重要概念&#xff0c;它允许一个对象以不同的形式表现。也就是说&#xff0c;在父类中定义的属性和方法&#xff0c;在子类继承后&#xff0c;可以有不同的数据类型或表现出不同的行为。这可以使得同一个属性或方法&#xff0…

带残差连接的ResNet18

目录 1 模型构建 1.1 残差单元 1.2 残差网络的整体结构 2 没有残差连接的ResNet18 2.1 模型训练 2.2 模型评价 3 带残差连接的ResNet18 3.1 模型训练 3.2 模型评价 4 与高层API实现版本的对比实验 总结 残差网络&#xff08;Residual Network&#xff0c;ResNet&#xff09;…

【TinyALSA全解析(二)】wav和pcm音频文件格式详解

wav和pcm音频文件格式详解 一、本文的目的二、wav和pcm格式文件介绍三、pcm格式文件解析四、wav文件内容解析4.1 文件内容描述4.2 实战分析 五、如何在各种音频格式之间进行转换 /******************************************************************************************…

中英双语大模型ChatGLM论文阅读笔记

论文传送门&#xff1a; [1] GLM: General Language Model Pretraining with Autoregressive Blank Infilling [2] Glm-130b: An open bilingual pre-trained model Github链接&#xff1a; THUDM/ChatGLM-6B 目录 笔记AbstractIntroductionThe design choices of GLM-130B 框架…

Python Pyvis库:可视化复杂网络结构的利器

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python Pyvis库&#xff1a;可视化复杂网络结构的利器&#xff0c;全文4000字&#xff0c;阅读大约12钟。 在数据科学和网络分析领域&#xff0c;理解和可视化复杂网络结构是…

华为设备使用python实现文件自动保存下载

实验目的&#xff1a; 公司有一台CE12800的设备&#xff0c;管理地址为172.16.1.2&#xff0c;现在需要编写自动化脚本&#xff0c;STELNET实现设备的自动保存配置文件&#xff0c;使用SFTP实现设备的文件下载。 实验拓扑&#xff1a; 实验步骤&#xff1a; 步骤1&#xff1…

深入Rust的模式匹配与枚举类型

今天&#xff0c;我们将深入探讨Rust语言中的两个强大特性&#xff1a;模式匹配&#xff08;Pattern Matching&#xff09;和枚举类型&#xff08;Enums&#xff09;。这两个特性是Rust提供的核心工具之一&#xff0c;它们在处理多种类型的数据和复杂的逻辑控制中发挥着关键作用…

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

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

Python中如何用栈实现队列

目录 一、引言 二、使用两个栈实现队列 三、性能分析 四、应用场景 五、代码示例 六、优缺点总结 一、引言 队列&#xff08;Queue&#xff09;和栈&#xff08;Stack&#xff09;是计算机科学中常用的数据结构。队列是一种特殊的线性表&#xff0c;只允许在表的前端进行…

HTTPS的介绍以及工作过程

目录 一.HTTPS是什么&#xff1f; HTTPS的介绍 HTTPS产生的背景 二.https的安全机制 加密是什么 如何加密 客户端如何获取公钥 总结 &#x1f381;个人主页&#xff1a;tq02的博客_CSDN博客-C语言,Java,Java数据结构领域博主 &#x1f3a5; 本文由 tq02 原创&#xff0…