在上篇文章咱們已經搭建好了基礎的開發環境,接下來會介紹如何引入 DVA 和 ANTD ,以及在引入過程當中須要注意的問題。這裏只會詳細的書寫部分組件,其餘的組件都是大同小異。你能夠在 github倉庫 中找到這些組件。css
這裏我簡單的畫了一個博客的輪廓圖。這樣在寫組件的過程當中有助於有個總體性的思路,不迷路…前端
blog ├─ dist # 輸出目錄 ├─ task # 這裏來放webpack處理和配置文件 ├─ src | ├─ assets # 靜態文件文件夾 | ├─ components # 組件 | | ├─ Home # Home 頁面的文件夾 | | ├─ Archive | | ├─ About | | ├─ Admin # 後臺界面文件夾 | | ├─ Header.js # 公共的 Header 組件 | | ├─ Footer.js # 公共的 Footer 組件 | | ├─ UserCard.js # 公共的 UserCard 組件 | | ├─ Login.js # 公共的 Login 組件 | ├─ containers # Redux 的容器組件 | | ├─ Home.js # Home 組件的容器 | | ├─ Archive.js | | ├─ About.js | | ├─ Admin # 後臺各界面的容器文件夾 | ├─ router.js # React 路由 | └ index.js # 入口文件 | package.json
Lightweight front-end framework based on redux, redux-saga and react-router@2.x. (Inspired by elm and choo)node
要知道 dva
是對 redux
, redux-saga
, react-router
的封裝,使用上有點像 express.js
,那麼你就要多少對他們有所瞭解,dva
的 github 倉庫 有詳細的入門指南、概念和示例,能夠先去了解一下 。react
更改入口文件 src/index.js
webpack
import dva from 'dva' const app = dva() app.router(require('./router')) app.start('#root')
新建路由文件 src/router.js
git
import React from 'react' import { Router, Route, IndexRoute, IndexRedirect } from 'dva/router' import AppLayout from './container/App' import Home from './container/Home' import Archive from './container/Archive' import About from './container/About' import Article from './container/Article' import AdminArticles from './container/Admin/Articles' import AdminKeywrods from './container/Admin/Keywords' import AdminEditor from './container/Admin/Editor' import AdminLayout from './container/Admin/Admin' export default ({history, app}) => { return ( <Router history={history}> <Route path="/" component={AppLayout}> <IndexRoute component={Home} /> <Route path="archive" component={Archive} /> <Route path="about" component={About} /> <Route path="article/:id" component={Article} /> <Route path="admin" component={AdminLayout}> <IndexRedirect to="articles" /> <Route path="articles" component={AdminArticles} /> <Route path="keywords" component={AdminKeywrods} /> <Route path="editor" component={AdminEditor} /> </Route> </Route> </Router> ) }
從這裏能夠看出, dva
本身在內部引入 react-router-redux ,而後使用 react-router-redux
提供的 combineReducers
把 routerRedux
合併到用戶的 reducers
中github
限於文章的篇幅,
dva
的model
的設計會放到下一次的文章來描述web
按需加載express
在引入 ANTD
以前,咱們先來實現 按需加載
。其實概念很簡單,就是咱們在引入一個樣式庫的時候,每每只會用到這個樣式庫的部分組件,可是工具會把整個組件庫都打包到咱們的項目中,這是咱們不想看到的。按需加載
就是用來打包咱們引入的組件,可使用 babel-plugin-import 來具體實現。json
在 task/config.js
的 babel-loader
的 plugins 配置中添加: ["import", { "libraryName": "antd", "style": true }]
自定義主題
由腳手架 atool-build 和 官網介紹,咱們已經本身配置並新建好了主題文件 theme.js
。
添加 less-loader 處理樣式文件
上節咱們只是添加了對 .module.less
文件進行編譯,在自定義主題時,須要對 less 變量進行覆蓋,因此要求 babel-plugin-import
的 style
選項設置爲 true
,讓它導出 antd
組件的 .less
樣式文件才能進行變量覆蓋操做。
在 task/config.js
中 module.rules
追加
{ test: function(path){ return /\.less$/.test(path) && !/\.module\.less$/.test(path) }, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ { loader: 'css-loader', }, { loader: 'postcss-loader', options: { plugins: postcssPlugins } }, { loader: 'less-loader', options: {"modifyVars": theme} } ] }) },
注意 /\.less/
至少會匹配到 .module.less
和 .less
文件,因此要排除 .module.less
,由於它須要被 css-module
處理。
你也可能會經過添加 exclude
, include
來對樣式庫中的 less
文件和本身編寫的文件進行區別,畢竟樣式庫確定都是從 node_modules
目錄中加載,而本身的是從 src
目錄下加載的。也正由於樣式庫是從 node_modules
目錄下加載的,因此這樣作可能會致使下降 webpack
的編譯速度。
在 /src/containers
下新建 App.js
import React, { PropTypes } from 'react' import { connect } from 'dva' import { Layout, Menu, Breadcrumb, Row, Col, Icon } from 'antd' import HeaderComponent from 'components/Header' import FooterComponent from 'components/Footer' import LoginModel from 'components/Login' const { Header, Content, Footer } = Layout const App = ({children, routes}) => { return ( <Layout> <Header> <HeaderComponent routes={routes}> <LoginModel doLogin={() => {}} /> </HeaderComponent> </Header> <Content style={{ margin: '24px 100px 0', background: '#fff', minHeight: 280, overflow: 'hidden' }}> {children} </Content> <Footer> <FooterComponent /> </Footer> </Layout> ) } export default connect()(App)
由於 dva
封裝了 redux
, 源文件 中也是直接導出 react-redux
的 connect
方法。因此在建立容器組件的時候仍是等同於 react-redux
。
注意,這個 App組件是做爲子路由組件的父組件,即
children
表明的就是那些子組件Home
,Archive
…
其餘的展現組件,即 /src/containers
文件夾下面的組件,都是大同小異,就不一一贅述。
咱們看到 src/container/App.js
展現組件,引入了一個 HeaderComponent
,在 src/components
下面新建一個 Header.js
import React from 'react' import { Layout, Menu, Breadcrumb, Row, Col } from 'antd' import { Router, Link } from 'dva/router' const HeaderComponent = (props) => { const { children, routes } = props const routePath = (routes[routes.length - 1] || {}).path || '/' return ( <div> <Row> <Col span={16}> <Menu mode="horizontal" defaultSelectedKeys={[routePath]} style={{ lineHeight: '64px', backgroundColor: 'transparent' }} > <Menu.Item key="/"><Link to="/">Home</Link></Menu.Item> <Menu.Item key="archive"><Link to="archive">Archive</Link></Menu.Item> <Menu.Item key="about"><Link to="about">About me</Link></Menu.Item> </Menu> </Col> <Col span={8}> <div style={{ lineHeight: '64px', float: 'right', padding: '0 20px' }}> {children} </div> </Col> </Row> </div> ) } export default HeaderComponent
這就是個普通的 React 的展現組件沒什麼好說的,這些組件能夠直接在 Antd
的官網上找到用法,並且都有示例代碼。
const routePath = (routes[routes.length - 1] || {}).path || '/'
找到路由路徑中的最後一個名稱,如 /home
中的 home
,做爲 Menu
的默認選中項,這樣在當前頁面刷新,就可讓當前頁面對應的導航高亮。
其餘的展現型組件也都是大同小異,你能夠在 github倉庫 中找到它們的實現。
在 task/config.js
中的 module.rules
追加:
{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: 'img/[name].[hash:7].[ext]' } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: 'fonts/[name].[hash:7].[ext]' } },
關於 url-loader
的配置方法,能夠在 webpack
的文檔中查看
這篇文章主要是引入了兩個重要的庫 dva
和 antd
,以及編寫部分展現組件。接下來,咱們會對 dva
的數據層,已經後臺初步搭建,同步進行先後端的開發。