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 = {// webpackwebpack: {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 = {// lessplugins: [{plugin: CracoLessPlugin,options: {lessLoaderOptions: {lessOptions: {// modifyVars: { '@primary-color': '#1DA57A' },javascriptEnabled: true}}}}],// webpackwebpack: {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 = {// lessplugins: [{plugin: CracoLessPlugin,options: {lessLoaderOptions: {lessOptions: {// modifyVars: { '@primary-color': '#1DA57A' },javascriptEnabled: true}}}}],// webpackwebpack: {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.mzph.cn/news/178029.shtml

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

相关文章

kafka2.x常用命令:创建topic,查看topic列表、分区、副本详情,删除topic,测试topic发送与消费

原创/朱季谦 接触kafka开发已经两年多&#xff0c;也看过关于kafka的一些书&#xff0c;但一直没有怎么对它做总结&#xff0c;借着最近正好在看《Apache Kafka实战》一书&#xff0c;同时自己又搭建了三台kafka服务器&#xff0c;正好可以做一些总结记录。 本文主要是记录如…

Spring --- 创建一个Spring项目

文章目录 创建一个Maven项目添加Spring框架支持添加启动类 创建一个Maven项目 注&#xff1a;我们需要使用 Maven 来管理依赖&#xff0c;所以需要创建一个Maven项目 添加Spring框架支持 注&#xff1a; 添加这两个依赖才能正确使用 Spring在添加依赖后记得刷新&#xff0c;把依…

【Nginx篇】Nginx轻松上手

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Unity2D-URP基于ShaderGraph创建带粒子特效的激光光束

文章目录 创建Shader新建Node: UV新建Node: Split......参数说明 基于Shader创建Material创建Line创建粒子系统StartVFX创建粒子材质更改粒子系统的材质设置透明模式设置粒子效果创建一个Beam设置EndVFX效果预览激光光束管理脚本最终预览 创建Shader Create --> Shader Gra…

零信任、SASE还在因不标准的身份系统难对接而无法发挥真正力量?这份标准化的解决方案助您一臂之力

身份安全是网络安全的一个重要领域&#xff0c;旨在确保用户的身份安全可信&#xff0c;防止未经授权的访问和数据泄漏等问题。目前主流的信息安全趋势强调可持续验证、多源信任评估、动态防护、可持续数据防护、一体化安全审计等&#xff0c;特别是零信任、SASE等技术均以身份…

vue elementUI 自定义框组织树,选择select下拉组织树横行滑动条出现方法

背景&#xff1a;最近公司开发需要使用到组织树进行组织结构的选择&#xff0c;在开发途中遇到两个次组织树已超过外框&#xff0c;但超出部分不显示横向滑动条。 自定义组织树框代码如下&#xff1a; <el-row><el-col :span"20" style"padding: 0px…

《数据结构、算法与应用C++语言描述》-线索二叉树的定义与C++实现

_23Threaded BinaryTree 可编译运行代码见&#xff1a;GIithub::Data-Structures-Algorithms-and-Applications/_24Threaded_BinaryTree 线索二叉树定义 在普通二叉树中&#xff0c;有很多nullptr指针被浪费了&#xff0c;可以将其利用起来。 首先我们要来看看这空指针有多少…

Leetcode刷题之设计循环队列(C语言版)

Leetcode刷题之设计循环队列&#xff08;C语言版&#xff09; 一、题目描述二、题目示例三、题目解析Ⅰ、typedef structⅡ、MyCircularQueue* myCircularQueueCreate(int k)Ⅲ、bool myCircularQueueIsEmpty(MyCircularQueue* obj)Ⅳ、bool myCircularQueueIsFull(MyCircularQ…

P19 C++ 构造函数的成员初始化列表

目录 前言 01 如果不用成员列表如何初始化变量 02 成员列表初始化 03 为什么要使用成员列表初始化呢&#xff1f; 04 案例代码 前言 本期我们聊聊构造函数初始化列表。 你应该经常使用成员初始化列表&#xff0c;如果你不喜欢这种代码风格&#xff0c;建议你还是慢慢习惯吧…

立即修复计算机显示msvcp110.dll丢失问题!4个快速解决方法大揭秘

在计算机使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“msvcp110.dll丢失”。这个错误通常会导致某些程序无法正常运行&#xff0c;给用户带来诸多不便。那么&#xff0c;当我们遇到这个问题时&#xff0c;应该如何进行修复呢&#xff1f;本文将…

搭建一个可以发送邮箱验证码的接口,内含前端处理 接口返回、请求处理

环境搭建 在node安装好的情况下&#xff08;一般vue环境有的node也有 没有可以使用winr回车输入node -v 有版本号则已经安装好 找一个空文件夹作为此项目文件夹 点击上面的地址栏输入cmd回车 输入npm init -y 再输入npm install nodemailer安装发送邮件的插件 环境配置 使用v…

vue3中toRef创建一个ref对象

为源响应式对象上的某个属性创建一个 ref对象, 二者内部操作的是同一个数据值, 更新时二者是同步的 区别ref: 拷贝了一份新的数据值单独操作, 更新时相互不影响 应用: 当要将 某个prop 的 ref 传递给复合函数时&#xff0c;toRef 很有用 父组件代码: <template><…

关于easy-es的聚合问题-已解决

es实体类&#xff1a; public class ChemicalES {IndexId(type IdType.CUSTOMIZE)private Long id;HighLightIndexField(fieldType FieldType.TEXT, analyzer "ik_max_word")private String name;IndexField(fieldType FieldType.KEYWORD)private List<Stri…

nginx 配置跨域(小皮面板)

本地开发的时候&#xff0c;前端请求后端&#xff0c;后端不能用域名请求&#xff0c;只能用端口模式&#xff0c;在小皮面板的话就是如下配置&#xff1a; 我的测试项目部署&#xff1a; 前端&#xff1a;http://localhost:8082 后端&#xff1a;http://localhost:8081 前端…

二百零八、Hive——HiveSQL异常:Select查询数据正常,但SQL语句加上group by查询数据为空

一、目的 在HiveSQL的DWD层中&#xff0c;需要对原始数据进行去重在内的清洗&#xff0c;结果一开始其他数据类型的清洗工作都正常&#xff0c;直到碰到转向比数据。 一般的SQL查询有数据&#xff0c;但是加上group by以后就没数据&#xff1b; 一般的SQL查询有数据&#xf…

Python实现WOA智能鲸鱼优化算法优化XGBoost分类模型(XGBClassifier算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 鲸鱼优化算法 (whale optimization algorithm,WOA)是 2016 年由澳大利亚格里菲斯大学的Mirjalili 等提…

uniapp基础-教程之HBuilderX基础常识篇02

uniapp创建项目时属性多为vue后缀&#xff1b;其中每个文件中都包含了三段式结构分别是template&#xff1b;script&#xff1b;style形势&#xff0c;分别是前端显示的画面以及js和css样式。 template&#xff1a;说大白话就是给别人看的&#xff0c;我们打开页面就可以看到的…

oracle查询开始时间和结束时间之间的连续月份

SELECT TO_CHAR(ADD_MONTHS(TO_DATE(2023-01,YYYY-MM), ROWNUM - 1), YYYY-MM) AS fmonth FROM DUALCONNECT BY ROWNUM < CEIL(MONTHS_BETWEEN(TO_DATE(2023-11, YYYY-MM), TO_DATE(2023-01,YYYY-MM))1)

附录11-math.h的常见方法

stdlib.h是做数学计算的头文件 目录 1 数学知识 1.1 弧度值/π 角度值/180 1.2 双曲函数 2 math.h 2.1 反余弦值 acos() 2.2 反正弦值 asin() 2.3 反正切值 atan() 2.4 两个数的反正切值 atan2() 2.5 向上取整 ceil() 2.6 余弦值 cos() 2.7 双曲余弦 c…

应用在触摸式面板中的电容式触摸芯片

触摸屏又称为“触控屏”、“触控面板”&#xff0c;是一种可接收触头等输入讯号的感应式液晶显示装置&#xff1b;当接触了屏幕上的图形按钮时&#xff0c;屏幕上的触觉反馈系统可根据预先编程的程式驱动各种连结装置&#xff0c;可用以取代机械式的按钮面板&#xff0c;并借由…