react+react-router+mobx+axios+less 搭建一個(gè)框架

之前做過(guò)react項(xiàng)目绕沈,但是沒(méi)有全面搭過(guò)框架锐想,順便研究一波mobx。
項(xiàng)目代碼github地址:https://github.com/lingziyb/react-mobx-demo

一乍狐、選react腳手架

  • 想:自己搭整個(gè)框架還是比較費(fèi)勁的赠摇,所以首先想到用它的腳手架來(lái)初始化一個(gè)大概的框架結(jié)構(gòu)。
  • 搜:開(kāi)始搜腳手架,最出名的就是facebook官方出版的create-react-app藕帜,那我們就用這個(gè)烫罩。

二、使用create-react-app初始化項(xiàng)目

工具會(huì)幫你初始化一個(gè)簡(jiǎn)單基本的項(xiàng)目并且會(huì)自動(dòng)幫你安裝項(xiàng)目所需要的各種依賴

  npx create-react-app my-app
  cd my-app
  yarn start   //或者npm start

此時(shí)瀏覽器會(huì)自動(dòng)訪問(wèn) http://localhost:3000/洽故,你會(huì)看到一個(gè) react 的歡迎界面贝攒,如下:代表你的項(xiàng)目已經(jīng)正常運(yùn)行了。

運(yùn)行后的頁(yè)面.png

三时甚、配置項(xiàng)

1. 展開(kāi)配置項(xiàng)

配置項(xiàng)打開(kāi)前.png

雖然項(xiàng)目已經(jīng)運(yùn)行隘弊,但是在項(xiàng)目目錄里是找不到webpack配置項(xiàng)的。比如荒适,我們想配置less梨熙、配置alias別名,這時(shí)我們需要做一個(gè)操作:展開(kāi)項(xiàng)目(eject)[ 注:這個(gè)一個(gè)不可逆過(guò)程刀诬,一旦你執(zhí)行了咽扇,就不能回到初始化 ] 。

  yarn eject   // 或者 npm run eject

再看項(xiàng)目結(jié)構(gòu)舅列,此時(shí)已多了一些其他目錄肌割,展開(kāi)config目錄卧蜓,里面就有webpack配置文件以及其他各種配置帐要,如下:

配置項(xiàng)打開(kāi)后.png

2. less配置

  yarn add less less-loader 
修改 webpack配置文件
  • 找到 webpack.config.dev.jswebpack.config.prod.js 文件,后綴 dev 表示開(kāi)發(fā)的配置弥奸,prod 表示是生產(chǎn)環(huán)境的配置榨惠,因此兩個(gè)配置文件都需要修改。
  • 修改webpack.config.dev.js盛霎,在modulerules字段中更改以下代碼
    更改前:
{
    test: /\.css$/,
    use: [
        require.resolve( 'style-loader' ),
        {
            loader: require.resolve( 'css-loader' ),
            options: {
            importLoaders: 1,
        },
        ...
    ],              
},

更改后:

{
    test: /\.(css|less)$/,    // 劃重點(diǎn)
    use: [
        require.resolve( 'style-loader' ),
        {
            loader: require.resolve( 'css-loader' ),
            options: {
            importLoaders: 1,
        },
        ...
        {
            loader: require.resolve( 'less-loader' ),    // 劃重點(diǎn)
        }
    ],              
},
  • 修改webpack.config.prod.js 赠橙,同理,在rules字段中更改以上代碼

四愤炸、引入路由

1. 更改src目錄結(jié)構(gòu)

  • 便于更符合實(shí)際項(xiàng)目場(chǎng)景期揪,我們?cè)?code>src下新建如下幾個(gè)文件夾:
    a. api文件夾存放ajax請(qǐng)求
    b. components文件夾存放組件
    c. pages文件夾存放頁(yè)面
    d. routes文件夾存放路由
    e. stores文件夾存放數(shù)據(jù)
    f. utils文件夾存放工具類(lèi)函數(shù)

2. 設(shè)置文件別名

既然有了文件夾來(lái)區(qū)分不同的功能,為了方便文件的相互规个,我們可以利用 webpack 來(lái)設(shè)置別名凤薛。

  • 修改config文件夾下的paths文件
module.exports = {
  ...
  appApi: resolveApp( 'src/api' ),
  appComponents: resolveApp('src/components'),
  appPages: resolveApp( 'src/pages' ),
  appRoutes: resolveApp('src/routes'),
  appStores: resolveApp( 'src/stores' ),
  appUtils: resolveApp('src/utils'),
  ...
  • 修改 webpack 配置項(xiàng) alias
alias: {
  ...
  api: paths.appApi,
  components: paths.appComponents,
  pages: paths.appPages,
  routes: paths.appRoutes,
  stores: paths.appStores,
  utils: paths.appUtils,
  ...

3. 安裝路由組件 react-router

  yarn add react-router react-router-dom
  • pages文件夾中新建home.jsx頁(yè)面和about.jsx頁(yè)面
    home.jsx
import React from 'react';
import { Link } from 'react-router-dom';

class Home extends React.Component {
    render() {
        return (
            <div>
                <p>這是首頁(yè)</p>
                <Link to="/about">go to About</Link>
            </div>
        );
    }
}

export default Home;

about.jsx

import React from 'react'
import { Link } from 'react-router-dom'

class About extends React.Component {
    render() {
        return (
            <div>
                <p>這是about頁(yè)面</p>
                <Link to="/">go to Home</Link>
            </div>
        )
    }
}

export default About;
  • routes文件夾中新建index.jsx頁(yè)面
import React from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'

import Home from 'pages/home';
import About from 'pages/about';

const Routes = () => (
    <Router>
        <div>
            <Route exact path="/" component={Home}/>
            <Route path="/about" component={About}/>
        </div>
    </Router>
)

export default Routes;
  • 為了頁(yè)面好看一點(diǎn)點(diǎn),我們寫(xiě)個(gè)App.less
.app {
    text-align: center;
    border: 1px solid #ddd;
    padding: 30px;
    p {
        color: green;
    }
}
  • 更改app.js文件
import React, { Component } from 'react';
import Routes from 'routes/index';
import './App.less'

class App extends Component {
    render() {
        return (
            <div className="app">
                <Routes />
            </div>
        );
    }
}

export default App;

此時(shí)首頁(yè)長(zhǎng)相:

首頁(yè).png

此時(shí)about頁(yè)長(zhǎng)相:

about頁(yè)

五诞仓、添加數(shù)據(jù)管理mobx

1. 按照依賴

yarn add mobx mobx-react

2.開(kāi)始使用

  • 使用 mobx 你還需要安裝 babel 的裝飾器插件缤苫,以及修改 babel 的配置
  yarn add babel-plugin-transform-decorators-legacy
  • 修改 package.json 文件中的 babel 參數(shù),或者在根目錄下新建一個(gè) .babelrc 文件
"babel": {
  "presets": [
    "react-app"
  ],
  "plugins": [
    "babel-plugin-transform-decorators-legacy"
  ]
...

現(xiàn)在墅拭,你可以在你的組件中使用 mobx 來(lái)管理你的狀態(tài)了活玲。關(guān)于 mobx 的使用,你可以訪問(wèn)官方文檔

3. 修改文件

  • stores里新建index.jshome.js舒憾、about.js镀钓。 【 注:home.js和about.js我用了兩種方式寫(xiě),都可以的镀迂〉穑】
    home.js
import { observable } from 'mobx';

const HomeStore = observable( {
    title: 'this is home page'
} );

export default HomeStore;

about.js

import { observable } from 'mobx';

class AboutStore {
    @observable title = 'this is about page';
}

export default new AboutStore();

index.js

import aboutStore from './about';
import homeStore from './home';

const store = {
    aboutStore,
    homeStore
};

export default store;
  • 修改app.js
import React, { Component } from 'react';
import Routes from 'routes/index';
import './App.less';
import { Provider } from 'mobx-react';
import stores from 'stores/index';

class App extends Component {
    render() {
        return (
            <div className="app">
                <Provider {...stores}>
                    <Routes />
                </Provider>
            </div>
        );
    }
}

export default App;
  • 修改pages里的home.jsx
import React from 'react';
import { Link } from 'react-router-dom';
import { inject } from 'mobx-react';

@inject( 'homeStore' )
class Home extends React.Component {
    render() {
        return (
            <div>
                <p>{this.props.homeStore.title}</p>
                <Link to="/about">go to About</Link>
            </div>
        );
    }
}

export default Home;
  • 修改pages里的about.jsx
import React from 'react'
import { Link } from 'react-router-dom'
import { inject } from 'mobx-react';

@inject( 'aboutStore' )
class About extends React.Component {
    render() {
        return (
            <div>
                <p>{ this.props.aboutStore.title }</p>
                <Link to="/">goto Home</Link>
            </div>
        )
    }
}

export default About;

這是現(xiàn)在的首頁(yè):【數(shù)據(jù)變了喲】

首頁(yè).png

這是現(xiàn)在的about頁(yè):【數(shù)據(jù)變了喲】

about頁(yè).png

六、數(shù)據(jù)請(qǐng)求axios

  yarn add axios
  • api文件夾里增加home.js
import axios from 'axios';

export default {

    /**
     * 獲取首頁(yè)列表頁(yè)數(shù)據(jù)
     * @returns {Promise.<*>}
     */
    async getList(){
        return await axios.get( 'http://lemonof.com:82/api/getList' ).then( ( res ) => res.data.data );
    }
}
  • 更改stores里的home.js
import { observable, action } from 'mobx';
import HomeApi from 'api/home';

const HomeStore = observable( {
    title: 'this is home page',
    list: [],

    // 獲取首頁(yè)數(shù)據(jù)
    async getList() {
        this.list = await HomeApi.getList();
    }
} );

export default HomeStore;
  • 更改pages里的home.jsx
import React from 'react';
import { Link } from 'react-router-dom';
import { observer, inject } from 'mobx-react';

@inject( 'homeStore' )
@observer
class Home extends React.Component {

    componentDidMount() {
        this.props.homeStore.getList();
    }

    render() {
        return (
            <div>
                <p>{this.props.homeStore.title}</p>
                <Link to="/about">go to About</Link>

                <div style={{ textAlign: 'left', width: '450px', margin: 'auto' }}>
                    <p>下面是列表數(shù)據(jù):</p>
                    {
                        this.props.homeStore.list && this.props.homeStore.list.map( ( el ) => {
                            return ( <div key={el.id}>標(biāo)題:{el.title}</div> )
                        } )
                    }
                </div>
            </div>
        );
    }
}

export default Home;

此時(shí)首頁(yè)長(zhǎng)相:【頁(yè)面沒(méi)有優(yōu)化招拙,請(qǐng)將就看】

首頁(yè).png

此時(shí)about頁(yè)長(zhǎng)相:【頁(yè)面沒(méi)有優(yōu)化唧瘾,請(qǐng)將就看】

about頁(yè).png

哇!終于寫(xiě)完了别凤。
后續(xù)我再把UI優(yōu)化下饰序。
最終項(xiàng)目代碼地址:https://github.com/lingziyb/react-mobx-demo

查閱文章有:
create-react-app全家桶router+mobx:http://www.reibang.com/p/2d54c2b3cfa3

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市规哪,隨后出現(xiàn)的幾起案子求豫,更是在濱河造成了極大的恐慌,老刑警劉巖诉稍,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝠嘉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡杯巨,警方通過(guò)查閱死者的電腦和手機(jī)蚤告,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)服爷,“玉大人杜恰,你說(shuō)我怎么就攤上這事∪栽矗” “怎么了心褐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)笼踩。 經(jīng)常有香客問(wèn)我逗爹,道長(zhǎng),這世上最難降的妖魔是什么嚎于? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任掘而,我火速辦了婚禮,結(jié)果婚禮上匾旭,老公的妹妹穿的比我還像新娘镣屹。我一直安慰自己,他們只是感情好价涝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布女蜈。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伪窖。 梳的紋絲不亂的頭發(fā)上逸寓,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音覆山,去河邊找鬼竹伸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛簇宽,可吹牛的內(nèi)容都是我干的勋篓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼魏割,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼譬嚣!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起钞它,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拜银,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后遭垛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體尼桶,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年锯仪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泵督。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卵酪,死狀恐怖幌蚊,靈堂內(nèi)的尸體忽然破棺而出谤碳,到底是詐尸還是另有隱情溃卡,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布蜒简,位于F島的核電站瘸羡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏搓茬。R本人自食惡果不足惜犹赖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望卷仑。 院中可真熱鬧峻村,春花似錦、人聲如沸锡凝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至张肾,卻和暖如春芭析,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吞瞪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工馁启, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芍秆。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓惯疙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親妖啥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子螟碎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容