1.安裝dva-cli npm install dva-cli -g npm install dva-cli -g 2.創建應用 dva new dvadashboard [dvadashboard為項目名] 3.安裝mockjs npm install mockjs --save 4.配置mock ...
1.安裝dva-cli
-
npm install dva-cli -g
2.創建應用
dva new dvadashboard
[dvadashboard為項目名]
3.安裝mockjs
- npm install mockjs --save
4.配置mockjs
- 打開.roadhogrc.mock.js 設置如下
const fs=require('fs'); const path=require('path'); const mockPath=path.join(__dirname+'/mock'); const mock={}; fs.readdirSync(mockPath).forEach(file=>{ Object.assign(mock,require('./mock/'+file)); }); module.exports=mock;
5.模擬用戶管理API
mock文件夾下新建user.js
API設置:
這裡只模擬倆個api 1.獲取所有用戶數據 2.添加用戶
const Mock=require('mockjs'); let db=Mock.mock({ 'data|3-6':[{ id:'@id', name:'@name', 'age|18-32':1 }] }); module.exports={ [`GET /api/users`](req,res){ res.status(200).json(db); }, [`POST /api/users`](req,res){ let user=req.body; console.log(req); user.id=Mock.mock('@id'); db.data.push(user); res.status(200).json(user); } }
接下來看一下api能不能使用, 進入項目目錄, 執行 npm start 啟動
進入預設頁面 預設埠號 8000 如下是項目啟動後預設頁面
訪問下api http://localhost:8000/api/users 好了,可以訪問 成功返回模擬用戶列表數據
6.安裝antd
npm install antd babel-plugin-import --save
babel-plugin-import 是用來按需載入 antd 的腳本和樣式的
安裝完成後,配置使用antd 修改.roadhogrc文件
添加 ["import",{ "libraryName":"antd","style":"css" }] 最後文件如下所示:
{ "entry": "src/index.js", "env": { "development": { "extraBabelPlugins": [ "dva-hmr", "transform-runtime", ["import",{ "libraryName":"antd","style":"css" }] ] }, "production": { "extraBabelPlugins": [ "transform-runtime", ["import",{ "libraryName":"antd","style":"css" }] ] } } }
7.定義路由
- 在src/routes/ 文件夾下新建 usersPage.js
這可能是最簡單的一個頁面了
import { connect } from 'dva'; const UserPage=()=>{ return ( <div> <h1>UserPage</h1> </div> ); }; export default connect()(UserPage);
- 註冊路由信息 修改src/router.js文件
順手加了個組件動態載入
import React from 'react'; import { Router, Route, Switch } from 'dva/router'; import dynamic from 'dva/dynamic'; import IndexPage from './routes/IndexPage'; function RouterConfig({ history,app }) { const UserPage=dynamic({ app, component:()=>import('./routes/usersPage') }); return ( <Router history={history}> <Switch> <Route path="/" exact component={IndexPage} /> <Route path="/users" exact component={UserPage} /> </Switch> </Router> ); } export default RouterConfig;
查看一下路由配置效果 訪問http://localhost:8000/#/users
顯示內容了
8.添加與服務端通訊
- 修改src/utils/request.js如下 用於提供基礎的ajax數據訪問
也有不少使用axio的 具體優缺點還沒研究。
import fetch from 'dva/fetch'; const checkStatus=(response)=>{ if(response.status>=200 && response.status<=200){ return response; } const error=new Error(response.statusText); error.response=response; throw error; }; export default async function request(url,options={}) { options.headers={ 'Content-Type':'application/json' } const response=await fetch(url,options); checkStatus(response); const data=await response.json(); return data; }
這裡為了理解簡單 省略一層 user.service (封裝基礎ajax通訊 提供業務介面) 在業務層中直接調用request里方法 【只是為了學習方便】
- 然後在src/models下新建user.js
import request from '../utils/request'; const User={ namespace:"user", state:{ list:[], visibleModal:false }, reducers:{ save(state,{ payload:{ data:list } }){ return { ...state, list }; } }, effects:{ * query({},{ call,put }){ const { data }=yield call(request,'/api/users',{ method:'GET' }); yield put({type:'save',payload:{ data }}); }, * create({ payload:{ user } },{ call,put }){ yield call(request,'/api/users',{ body:JSON.stringify(user), method:'POST' }); yield put({type:'query',payload:{ }}); } }, subscriptions:{ setup({ dispatch,history }){ console.log('running subscriptions ...'); return history.listen(({ pathname,search })=>{ console.log(`pathname: ${pathname}`); dispatch({ type:'query'}); }); } } }; export default User;
這裡主要體現dva對redux react-saga的封裝處理 一目瞭然了
- 然後註冊model 修改路由處代碼為:
import React from 'react'; import { Router, Route, Switch } from 'dva/router'; import dynamic from 'dva/dynamic'; import IndexPage from './routes/IndexPage'; function RouterConfig({ history,app }) { const UserPage=dynamic({ app, models:()=>[ import('./models/user') ], component:()=>import('./routes/usersPage') }); return ( <Router history={history}> <Switch> <Route path="/" exact component={IndexPage} /> <Route path="/users" exact component={UserPage} /> </Switch> </Router> ); } export default RouterConfig;
9.新建用戶數據列表組件 使用antd的Tabel承載
順手也把添加用戶的表單建了吧
user.js
import { Table,Button } from 'antd'; import { connect } from 'dva'; import UserModal from './create'; const UserTable = ({ list,dispatch }) => { const createUser=(user)=>{ dispatch({ type:'user/create', payload:{ user } }); }; const columns=[ { Title:'ID', dataIndex:'id' }, { Title:'NAME', dataIndex:'name' }, { Title:'AGE', dataIndex:'age' } ]; return ( <div> <UserModal record={ {} } ok={ createUser }> <Button type="primary">NEW</Button> </UserModal> <Table columns={ columns } dataSource={ list } rowKey={ t=>t.id } pagination={ false }> {/* users datatable */} </Table> </div> ); }; export default connect(({ user }) => { console.log(user); return { list: user.list }; })(UserTable);
create.js
import React,{ Component } from 'react'; import { Modal,Form,Input } from 'antd'; class UserModal extends Component{ constructor(props){ super(props); this.state={ visible:false }; } render(){ const { children,form:{ getFieldDecorator },record,ok }=this.props; const showModal=()=>{ this.setState({ visible:true }); }; const hideModal=()=>{ this.setState({ visible:false }); }; const save=()=>{ this.props.form.validateFields((err,val)=>{ //val ==> record // console.log(val); ok(val); hideModal(); }); }; return ( <div> <span onClick={ showModal }> { children } </span> <Modal title="Create User" visible={ this.state.visible } onCancel={ hideModal } onOk={ save }> <Form> <Form.Item label="Name"> { getFieldDecorator('name', { initialValue: record.name })(<Input />) } </Form.Item> <Form.Item> { getFieldDecorator('age',{ initialValue:record.age })(<Input />) } </Form.Item> </Form> </Modal> </div> ); }; } export default Form.create()(UserModal);
usersPage.js
import { connect } from 'dva'; import Main from '../components/layout/main'; import UserTable from '../components/user/user'; const UserPage=()=>{ return ( <Main> <h1>UserPage</h1> <UserTable /> </Main> ); }; export default connect()(UserPage);
10.效果演示
11.源碼下載
或者 https://pan.baidu.com/s/1bo1R7o7