阅读 1070

基于react+antd+dva 构建后台管理系统

react.jpg hello,大家好今天让我们来搭建个基于react的前端系统架构吧!附上源码地址gitee.com/SongTaoo/re…

一、初始化react脚手架

首先我们需要安装react脚手架,命令行执行npx create-react-app xx,等待完成,此时我们cd到xx,执行npm run eject展开脚手架的配置项,因为我们需要做一些配置

  1. 在scripts文件夹下面找到start.js 43行const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 9999修改我们的端口号

  2. 我比较喜欢less所以我们配置一下less,在config文件夹下找到webpack.config.js,在63行下满加上const lessRegex = /.less/ const lessModuleRegex = /\.module\.less/复制sass的配置,修改为less即可,最后我们需要安装下less和less-loader,命令行执行npm install --save less less-loader

注意这里有个坑:如果less-loader版本安装高的话会报错,我们降到6.0.0即可

  1. 删文件,根据个人喜好没默认生成的没用的文件都删除掉,我这里只保留了,index.js app.js reportWebVitals.js

二、安装dva配置models(redux)

用过dva的都知道,dva对redux,router进行了封装便于我们进行傻瓜式的操作

  1. 执行npm install --save dva安装dva
  2. 安装完毕后在src目标下创建models文件件,用来存储数据,也就是我们以前的redux
  3. 在models下先创建base.js,这个主要用来存储我们通用的一些数据,比如,用户信息,全局装填...

代码如下:

const base = {
    namespace: 'base',
    state: {
        name: '秋水无痕'
    },
    reducers: {},
    effects: {}
}

export default base
复制代码

以上就是我们的配置文件,如果有多个,直接创建多个js就行了 在src目录下创建dvaApp.js用来配置dva的一些信息

import dva from 'dva'
import { createHashHistory } from 'history'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'

const persistConfig = {
    // redux持久化配置
    key: 'root',
    storage: storage,
    blacklist: []
}

// 生成dva应用,配置一些hooks
const app = dva({
    history: createHashHistory(),
    onError(e) {
        // 捕捉effect中执行的报错
        // subscription中通过done触发的错误
        console.log(e)
    },
    onAction() {
        return (next) => (action) => next(action)
    },
    // 可监听state状态的变化
    onStateChange() {},

    onReducer(reducer) {
        return persistReducer(persistConfig, reducer)
    }
})
window.onload = () => persistStore(app._store)

export default app

复制代码

我这里使用了redux-persist去做数据的持久化存储,blacklist数组下写上models下的文件名,即可对当前的数据进行持久化存储也就是保存早localstrong中一份,因为dva的models是根据路由注入的所以这里我们需要去创建路由,把数据和页面结合起来

三、创建router

在src目录下创建router文件夹,文件夹下面分别创建index.jsx routerView.jsx history.js routes.js四个文件

1:创建history.js,用来获取路由信息

const { createHashHistory } = require('history')
export default createHashHistory()
复制代码

2:创建index.jsx

import React from 'react'
// import { BrowserRouter as Router } from 'dva/router';
import { HashRouter as Router } from 'dva/router'
import routes from './routes'
import RouterView from './routerView'
export default function SetRouter() {
    if (!routes || routes.length === 0) return null
    return (
        <Router>
            <RouterView routes={routes} />
        </Router>
    )
}
复制代码

3:创建routerView.jsx,遍历routes生成路由展示

import React from 'react'
import { Switch, Route } from 'dva/router'

function RouterView(props) {
    const { routes } = props
    if (!routes || routes.length === 0) return null
    return (
        <Switch>
            {routes.map((item) => {
                const { path } = item
                return (
                    <Route
                        key={item.path}
                        path={path}
                        exact={item.exact}
                        render={(renderProps) => {
                            const Component = item.component
                            if (!Component) return null

                            return <Component {...renderProps} {...item} />
                        }}
                    />
                )
            })}
        </Switch>
    )
}
RouterView.defaultProps = {
    routes: []
}

export default RouterView

复制代码

4:创建routes文件并且关联上models

import dynamic from 'dva/dynamic'
import app from '../appDva'

// 如果有公用的数据需要共享就写在base中
const commonArr = [import('../models/base')]

const createComponent = (component, arr = []) =>
    dynamic({
        app,
        models: () => [...commonArr, ...arr],
        component
    })

// [import('../models/...')] //这个是用来引入rudux
const Home = createComponent(() => import('@/pages/home'))
const Login = createComponent(() => import('@/pages/login'))
const Center = createComponent(() => import('@/pages/center'))
const HomeName = createComponent(() => import('@/pages/homename'))
// 注意这里需要做用户权限的筛选,如果想简单一点,给后端协商好,通过后端的配置返回下面这个数据即可,复杂的话就需要返回用户的权限,我们对数组进行递归便利生成一个新的数组,
const routes = [
    {
        path: '/home',
        component: Home,
        name: '我的主页',
        routes: [

            {
                path: '/home/name',
                component: HomeName,
                exact: true,
                name: '我的信息'
            }
        ]
    },
    {
        path: '/center',
        component: Center,
        name: '个人中心'
    },
    {
        path: '/login',
        component: Login,
        name: '登录'
    }
]

export default routes

复制代码

解释:dva为我们提供了dynamic函数去对路由做懒加载,优化项目性能,我这里封装了一个函数,默认将base下的数据注入所有的路由页面,如果需要其他的数据,只需为createComponent函数传递第二个参数就可以了

四、修改入口文件让项目跑起来

app.js修改为如下

import React from 'react'
import SetRouter from './router'
import './app.less'
export default function App() {
    return <SetRouter />
}

复制代码

index.js修改为如下

import reportWebVitals from './reportWebVitals'
import dvaApp from './appDva'
import App from './App'
dvaApp.router(App)
dvaApp.start('#root')

reportWebVitals()

复制代码

在src文件夹下面创建pages文件夹,写上一些页面与我们的路由对应上,执行npm start,这时候就可以看到我们跑起来的项目了。

五、配置antd

这个很简单看着api整就行了,不懂的可以看这里,传送门

六、配置eslint约束代码

由于我们使用的是最新的react17.0.2,所以可以直接对eslint的默认配置进行覆盖 在src文件下创建.eslintrc.js,内容如下:

module.exports = {
    env: {
        node: true,
        mocha: true,
        jest: true,
        es6: true,
        browser: true
    },
    extends: [
        'eslint:recommended',
        'plugin:react/recommended',
        'plugin:react-hooks/recommended'   
    ],
    parser: 'babel-eslint',
    parserOptions: {
        ecmaFeatures: {
            jsx: true
        },
        ecmaVersion: 6,
        sourceType: 'module'
    },
    plugins: ['react', 'jsx-a11y', 'react-hooks', 'prettier'],
    settings: {
        react: {
            version: 'detect'
        }
    },
    globals: {
        JSX: true,
        React: true,
        NodeJS: true,
        Promise: true
    },
    rules: {
        'no-console': 'off',
        'consistent-return': 2,
        curly: [2, 'multi-or-nest'],
        'dot-location': 0,
        eqeqeq: 2,
        'no-alert': 2,
        'no-eq-null': 2,
        'no-lone-blocks': 2,
        'no-return-await': 2,
        'no-unused-expressions': 2,
        'no-label-var': 1,
        'array-bracket-spacing': 2,
        'brace-style': 0,
        'comma-spacing': 1,
        'consistent-this': 1,
        'eol-last': 0,
        'multiline-ternary': [1, 'always-multiline'],
        'new-cap': [
            2,
            {
                capIsNew: false
            }
        ],
        'no-trailing-spaces': 0,
        semi: ['error', 'never'],
        'space-before-blocks': 2,
        'space-in-parens': 2,
        'spaced-comment': 2,
        'switch-colon-spacing': [
            'error',
            {
                after: true,
                before: false
            }
        ],
        'arrow-spacing': 2,
        quotes: [0, 'single'],
        'key-spacing': 2,
        'comma-dangle': ['error', 'never'],
        'react-hooks/exhaustive-deps': 0,
        'no-empty-function': 0,
        'react-native/no-inline-styles': 0,
        'react/forbid-prop-types': 0,
        'react/prop-types': 0,
        'react/display-name': 0,
        'prefer-promise-reject-errors': 0,
        'react/no-array-index-key': 2,
        'react/no-unused-state': 2,
        'react/jsx-indent-props': 2,
        'react/jsx-no-comment-textnodes': 1,
        'react/jsx-no-duplicate-props': 2,
        'react/jsx-no-target-blank': [
            1,
            {
                enforceDynamicLinks: 'always'
            }
        ],
        'react/jsx-no-undef': 2,
        'react/jsx-props-no-multi-spaces': 1,
        'react/jsx-tag-spacing': 1,
        'react/jsx-uses-vars': 2,
        'react/jsx-wrap-multilines': 2,
        'react-hooks/rules-of-hooks': 2
    }
}

复制代码

在src文件夹下面创建.eslintignore文件用来保存忽略的eslint检查的文件

node_modules
dist/
test
build/
public/
scripts/
static/
config/
复制代码

如果你使用的是vscode编辑器,那么安装eslint插件后在保存代码时就可以进行修正了。 为了更加严谨的做eslint规范,我这里增加了comit时的验证

package.json新增,控制台安装pre-commit即可

"scripts": {
        "start": "node scripts/start.js",
        "build": "node scripts/build.js",
        "test": "node scripts/test.js",
        "lint": "eslint . --fix" //新增,用来修改代码
    },
    "pre-commit": [
        "lint" //新增验证
    ],
复制代码

好了,到这里我们的架构已经完美的搭建好了,是不是很简单啊!看完别忘收藏点赞额!

文章分类
前端
文章标签