项目构建
## 创建React项目npm init vite## 创建Git仓库git init## 代码检测工具npm install -D eslint## 格式化npx eslint --init## 代码规范npx mrm lint-staged## 代码提交规范npm install --save-dev @commitlint/config-conventional @commitlint/cli## 设置echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js## 添加ommit-msg 文件npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"
create-react-app区分环境
// 安装dotenv-cli"scripts": {"dev": "dotenv -e .env.dev craco start","build:test": "dotenv -e .env.test craco build","build:prod": "dotenv -e .env.prod craco build",},
vite插件
- Vite 代码拆包插件: vite-plugin-chunk-split
icon解决方案
icon={React.createElement(Icons[item.icon])}
动态css
```javascript const path = require(‘path’) const Webpackbar = require(‘webpackbar’) const CircularDependencyPlugin = require(‘circular-dependency-plugin’) const CompressionPlugin = require(‘compression-webpack-plugin’)<div className={[`${styles['name1']}`,`${styles['name2']}`].join(' ')}></div>
module.exports = { babel: { presets: [‘@babel/preset-env’], compact: true, }, webpack: { configure: (webpackConfig, { env, paths }) => { webpackConfig.stats = ‘errors-only’ // 更名打包文件夹 paths.appBuild = ‘dist’ webpackConfig.output = { …webpackConfig.output, path: path.resolve(_dirname, ‘dist’), publicPath: ‘/‘, } // 抽离公用模块 webpackConfig.optimization.splitChunks = { chunks: ‘all’, cacheGroups: { commons: { name: ‘chunk-commons’, test: /[\/]node_modules[\/]/, priority: 10, chunks: ‘initial’, }, douyinfe: { name: ‘chunk-douyinfe’, test: /[\/]node_modules[\/]?@douyinfe(.)/, priority: 20, }, echarts: { name: ‘chunk-echarts’, test: /[\/]nodemodules[\/]?echarts(.)/, priority: 30, }, brafteditor: { name: ‘chunk-brafteditor’, test: /[\/]nodemodules[\/]?braft-editor(.*)/, priority: 40, }, }, } return webpackConfig }, plugins: [ // 代码压缩 new CompressionPlugin({ algorithm: ‘gzip’, test: new RegExp(‘\.(‘ + [‘js’, ‘css’].join(‘|’) + ‘)$’), threshold: 10240, minRatio: 0.8, }), // 循环引用的检测 new CircularDependencyPlugin({ exclude: /node_modules/, include: /src/, failOnError: true, allowAsyncCycles: false, cwd: process.cwd(), }), // 进度条显示 new Webpackbar({ profile: true }), ], }, }
<a name="MBcIn"></a># react-color```bashimport { useState } from 'react'import { SketchPicker } from 'react-color'import { IconChevronDown } from '@douyinfe/semi-icons'import './index.scss'const CustomColors = ({ color, setColor }) => {const [show, setShow] = useState(false)return (<div className="customcolors"><div className='customcolors-color' style={{ background: color }} onClick={() => setShow(!show)} /><IconChevronDown className='customcolors-close' onClick={() => setShow(!show)} />{show && <SketchPicker className='customcolors-popover' color={color} onChange={(color) => setColor(`rgba(${color.rgb.r},${color.rgb.g},${color.rgb.b},${color.rgb.a})`)} />}</div>)}export default CustomColors
.customcolors {position: relative;box-sizing: border-box;width: 100%;height: 30px;padding: 5px;border-radius: 3px;background-color: #2e32380d;.customcolors-color {width: calc(100% - #{26px});height: 100%;border-radius: 3px;}.customcolors-popover {position: fixed;z-index: 2;}.customcolors-close {font-size: 16px;position: absolute;top: 8px;right: 8px;color: #1c1f239e;}}
react-cookies
import Cookie from 'react-cookies'
// 存储
Cookie.save('name', data, { paht: '/' })
// 读取
Cookie.load('name')
// 删除
Cookie.remove('name')
倒计时
import { useState, useEffect } from 'react'
let timer = null
const Index = ({ num = 60 }) => {
const [time, setTime] = useState(0)
// 默认
useEffect(() => {
timer && clearInterval(timer)
setTime(num)
return () => timer && clearInterval(timer)
}, [])
// 执行
useEffect(() => {
if (time === num) {
timer = setInterval(() => setTime(time => --time), 1000)
} else if (time === 0) {
clearInterval(timer)
}
}, [time])
return time
}
export default Index
// 默认行为
useEffect(()=>{
if (Timer) {
clearInterval(Timer)
}
Timer = setInterval(function () {
const openid = getStorageSync('OPENID')||false
if (openid) {
const Pages = getCurrentInstance()
let routerData = Pages.router.params
if (routerData.customerId) {
setOpen(openid)
setObj(routerData)
openPay(routerData,openid)
clearInterval(Timer)
Timer = null
}
}
}, 200);
return ()=>{
if (Timer) {
clearInterval(Timer)
}
}
},[])
子组件导出
<Box>
<Box.Left>
Left
</Box.Left>
<Box.Right>
Right
</Box.Right>
</Box>
import React from 'react';
const Box = ({children = null}) =>
<div>
{children}
</div>;
const Left = ({children = null}) =>
<div>
{children}
</div>;
const Right = ({children = null}) =>
<div>
{children}
</div>;
Box.Left = Left;
Box.Right = Right;
export default Box;
