天天看點

使用 create-react-app + react-router-dom + axios + antd + react-redux 建構 React 項目(1)1、安裝、建構 複制代碼2、項目目錄3、antd4、axios5、router6、scss7、修改端口号8、react-redux

1、安裝、建構 複制代碼

全局安裝

npm install -g create-react-app
           

建構一個my-app的項目

npx create-react-app my-app
cd my-app
           

啟動編譯目前的React項目,并自動打開 http://localhost:3000/

npm start
           

2、項目目錄

// 預設的

├── package.json
├── public                  # 這個是webpack的配置的靜态目錄
│   ├── favicon.ico
│   ├── index.html          # 預設是單頁面應用,這個是最終的html的基礎模闆
│   └── manifest.json
├── src
│   ├── App.css             # App根元件的css
│   ├── App.js              # App元件代碼
│   ├── App.test.js
│   ├── index.css           # 啟動檔案樣式
│   ├── index.js            # 啟動的檔案(開始執行的入口)!!!!
│   ├── logo.svg
│   └── serviceWorker.js
└── yarn.lock  
           

// 修改後的

├── package.json
├── public                  # 這個是webpack的配置的靜态目錄
│   ├── favicon.ico
│   ├── index.html          # 預設是單頁面應用,這個是最終的html的基礎模闆
│   └── manifest.json
├── src
│   ├── assets            # 圖檔等靜态資源
│   ├── redux             # 狀态
│   │      ├── action.js                 # action
│   │      ├──reducerjs              # reducer
│   │      └── index.js                 # 主檔案
│   ├── router             # 路由
│   │      ├── config.js                 # 配置
│   │      ├── FrontendAuth.js      # 路由守衛
│   │      └── index.js                 # 主檔案
│   ├── serve            # 請求
│   │      ├── index.js            # axio
│   ├── views            # 頁面
│   ├── App.css             # App根元件的css
│   ├── App.js              # App元件代碼
│   ├── App.test.js
│   ├── index.css           # 啟動檔案樣式
│   ├── index.js            # 啟動的檔案(開始執行的入口)!!!!
│   ├── logo.svg
│   └── serviceWorker.js
└── yarn.lock          
           

3、antd

yarn add antd
           
修改 src/App.css,在檔案頂部引入 antd/dist/antd.css。
@import '~antd/dist/antd.css';

.App {
  text-align: center;
}

...
           

antd 目前的預設文案是英文,如果需要使用其他語言,可以參考下面的方案。

antd 提供了一個 React 元件 ConfigProvider 用于全局配置國際化文案。

import zhCN from 'antd/es/locale/zh_CN';

return (
  <ConfigProvider locale={zhCN}>
    <App />
  </ConfigProvider>
);
           

4、axios

yarn add axios
           

/src/serve/index.js,統一配置并綁定到react上

import React from 'react';
import axios from 'axios';
axios.defaults.headers['Content-Type'] = 'application/json';


let config = {
  baseURL: '',
  timeout: 60 * 1000, // Timeout
};
const _axios = axios.create(config);
_axios.interceptors.request.use(
  (config) => {
    // Do something before request is sent
    config.headers['Authorization'] = '';
    return config;
  },
  (error) => {
    // Do something with request error
    return Promise.reject(error);
  }
);

// Add a response interceptor
_axios.interceptors.response.use(
  (response) => {
    // Do something with response data
    return response
  },
  (error) => {
    // Do something with response error
    return Promise.reject();
  }
);
React.Component.prototype.$axios = _axios;
           

5、router

yarn add react-router-dom
           

/src/router/config.js

import login from '../views/login';
import record from '../views/record';
import home from '../views/home';


export const routerConfig = [
  {
    path:'/',
    component:home,
    auth:true,
  },{
    path:'/record',
    component:record,
    //auth:true,
  },{
    path:'/login',
    component:login,
  }
];
           

/src/router/FrontendAuth.js

import React, {Component} from 'react';
import {Route, Redirect} from 'react-router-dom';

export class FrontendAuth extends Component {
  render() {
    const {location, config} = this.props;
    const {pathname} = location;
    const isLogin = localStorage.getItem('__config_center_token')

    // 如果該路由不用進行權限校驗,登入狀态下登陸頁除外
    // 因為登陸後,無法跳轉到登陸頁
    // 這部分代碼,是為了在非登陸狀态下,通路不需要權限校驗的路由
    const targetRouterConfig = config.find((v) => v.path === pathname);
    if (targetRouterConfig && !targetRouterConfig.auth && !isLogin) {
      const {component} = targetRouterConfig;
      return <Route exact path={pathname} component={component}/>
    }

    if (isLogin) {
      // 如果是登陸狀态,想要跳轉到登陸,重定向到首頁
      if (pathname === '/login') {
        return <Redirect to='/'/>
      } else {
        // 如果路由合法,就跳轉到相應的路由
        if (targetRouterConfig) {
          return <Route path={pathname} component={targetRouterConfig.component}/>
        } else {
          // 如果路由不合法,重定向到 404 頁面
          return <Redirect to='/404'/>
        }
      }
    } else {
      // 非登陸狀态下,當路由合法時且需要權限校驗時,跳轉到登陸頁面,要求登陸
      if (targetRouterConfig && targetRouterConfig.auth) {
        return <Redirect to='/login'/>
      } else {
        // 非登陸狀态下,路由不合法時,重定向至 404
        return <Redirect to='/404'/>
      }
    }
  }
}
           

/src/router/index.js

import React, { Component } from 'react';
import { Switch} from 'react-router-dom';

import { FrontendAuth } from './FrontendAuth';
import { routerConfig } from './config';


class Routes extends Component {
  render() {
    return (
      <Switch>
        <FrontendAuth config={routerConfig} />
      </Switch>
    )
  }
}

export default Routes
           

app.js

import React, { Component } from 'react';// 原著這裡應該沒有粘貼上 我粘上就不報錯了 

import {BrowserRouter as Router} from 'react-router-dom';
import Routes from './router/index'

class App extends Component  {
  render() {
    return (
      <Router>
        <Routes></Routes>
      </Router>
    );
  }
}

export default App;
           

6、scss

安裝完後,隻要把sass檔案改成.scss就行了
npm install node-sass sass-loader --save
           

7、修改端口号

項目預設端口号是3000,如下可以更改:

在 package.json 中修改

8、react-redux

redux不是項目必需的,如果你不确定是否需要,那就是不需要,在react無法實作時,再考慮。

/src/redux/action.js

/*
 * action 類型
 */

export const COUNT = 'COUNT';
/*
 * 初始值
 */

export const config = {
    count:1000
};


/*
 * action 建立函數
 */

export function setCount(value) {
    return { type: COUNT, value }
}
           

/src/redux/reducer.js

//這是action
import {
  COUNT
} from './actions'

//這是reducer
const reducer = (state , action) => {
  switch (action.type) {
    case COUNT:
      let count =  action.value;
      return {...state,...{count}};
    default:
      return state;
  }
};
export default reducer
           

/src/redux/index.js

import { createStore } from 'redux';
import {config} from './actions';
import reducer from './reducer';
let store = createStore(reducer,config);

export default store
           

/src/index.js

import { Provider } from 'react-redux'
import store from './redux/index'

ReactDOM.render(
  <ConfigProvider locale={zhCN}>
    <Provider store={store}>
      <App />
    </Provider>
  </ConfigProvider>, document.getElementById('root'));
           
// 頁面調用示例
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
  setCount,
} from '../redux/actions'

class ReduxTest extends Component {

  componentDidMount() {
    console.log(this.props)
  }
  render() {
    const { PayIncrease,tiger } = this.props;
    return (
      <div className="App">
        <h2>當月工資為{tiger}</h2>
        <button onClick={PayIncrease}>升職加薪</button>
      </div>
    );
  }
}
//需要渲染什麼資料
function mapStateToProps(state) {
  return {
    tiger: state.count
  }
}
//需要觸發什麼行為
function mapDispatchToProps(dispatch) {
  return {
    PayIncrease: () => dispatch(setCount(99999)),
  }
}

export default ReduxTest = connect(mapStateToProps, mapDispatchToProps)(ReduxTest)
           

轉自:Jade_g