项目构建

  1. ## 创建React项目
  2. npm init vite
  3. ## 创建Git仓库
  4. git init
  5. ## 代码检测工具
  6. npm install -D eslint
  7. ## 格式化
  8. npx eslint --init
  9. ## 代码规范
  10. npx mrm lint-staged
  11. ## 代码提交规范
  12. npm install --save-dev @commitlint/config-conventional @commitlint/cli
  13. ## 设置
  14. echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
  15. ## 添加ommit-msg 文件
  16. npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"

create-react-app区分环境

  1. // 安装dotenv-cli
  2. "scripts": {
  3. "dev": "dotenv -e .env.dev craco start",
  4. "build:test": "dotenv -e .env.test craco build",
  5. "build:prod": "dotenv -e .env.prod craco build",
  6. },

vite插件

  • Vite 代码拆包插件: vite-plugin-chunk-split

    icon解决方案

    1. icon={React.createElement(Icons[item.icon])}

    动态css

    1. <div className={[`${styles['name1']}`,`${styles['name2']}`].join(' ')}></div>
    ```javascript const path = require(‘path’) const Webpackbar = require(‘webpackbar’) const CircularDependencyPlugin = require(‘circular-dependency-plugin’) const CompressionPlugin = require(‘compression-webpack-plugin’)

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 }), ], }, }

  1. <a name="MBcIn"></a>
  2. # react-color
  3. ```bash
  4. import { useState } from 'react'
  5. import { SketchPicker } from 'react-color'
  6. import { IconChevronDown } from '@douyinfe/semi-icons'
  7. import './index.scss'
  8. const CustomColors = ({ color, setColor }) => {
  9. const [show, setShow] = useState(false)
  10. return (
  11. <div className="customcolors">
  12. <div className='customcolors-color' style={{ background: color }} onClick={() => setShow(!show)} />
  13. <IconChevronDown className='customcolors-close' onClick={() => setShow(!show)} />
  14. {show && <SketchPicker className='customcolors-popover' color={color} onChange={(color) => setColor(`rgba(${color.rgb.r},${color.rgb.g},${color.rgb.b},${color.rgb.a})`)} />}
  15. </div>
  16. )
  17. }
  18. export default CustomColors
  1. .customcolors {
  2. position: relative;
  3. box-sizing: border-box;
  4. width: 100%;
  5. height: 30px;
  6. padding: 5px;
  7. border-radius: 3px;
  8. background-color: #2e32380d;
  9. .customcolors-color {
  10. width: calc(100% - #{26px});
  11. height: 100%;
  12. border-radius: 3px;
  13. }
  14. .customcolors-popover {
  15. position: fixed;
  16. z-index: 2;
  17. }
  18. .customcolors-close {
  19. font-size: 16px;
  20. position: absolute;
  21. top: 8px;
  22. right: 8px;
  23. color: #1c1f239e;
  24. }
  25. }

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;