├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitignore
├── README.md
├── mock
└── example.js
├── package.json
├── proxy.config.js
├── src
├── assets
│ └── yay.jpg
├── components
│ ├── Example.js
│ ├── Silder.js
│ └── breadcrumb.js
├── config
│ └── config.js
├── index.css
├── index.html
├── index.js
├── models
│ ├── 11.js
│ ├── common.js
│ └── example.js
├── router.js
├── routes
│ ├── 1-1.js
│ ├── 1-2.js
│ ├── 2-1.js
│ ├── 2-2.js
│ ├── 3-1.js
│ ├── 3-2.js
│ ├── 3-3.js
│ ├── 3-4.js
│ ├── IndexPage.css
│ └── IndexPage.js
├── services
│ └── example.js
├── tests
│ └── models
│ │ └── example-test.js
└── utils
│ ├── query.js
│ └── request.js
└── webpack.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [Makefile]
16 | indent_style = tab
17 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | src/**/*-test.js
2 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": "eslint-config-airbnb",
4 | "rules": {
5 | "spaced-comment": [0],
6 | "no-unused-vars": [0],
7 | "no-empty": [0],
8 | "react/wrap-multilines": [0],
9 | "react/no-multi-comp": [0],
10 | "no-constant-condition": [0],
11 | "react/jsx-no-bind": [0],
12 | "react/prop-types": [0],
13 | "arrow-body-style": [0],
14 | "react/prefer-stateless-function": [0],
15 | "semi": [0],
16 | "global-require": [0],
17 | "no-shadow": [0],
18 | "no-useless-computed-key": [0],
19 | "no-underscore-dangle": [0]
20 | },
21 | "ecmaFeatures": {
22 | "experimentalObjectRestSpread": true
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 这是一个基于dva的基础小项目,主要是配合自己的博客文章,作为示范demo使用。
2 |
3 | [基于dva-cli&antd的react项目实战](http://que01.top/2016/11/20/dva-react/)
4 |
--------------------------------------------------------------------------------
/mock/example.js:
--------------------------------------------------------------------------------
1 | var co = require('co');
2 | var fetch = require('node-fetch');
3 | var safeeval = require('safe-eval');
4 | var mockjs = require('mockjs');
5 | var Host = 'http://rap.taobao.org/mockjs/5889'
6 |
7 | function mockMapFun(req,res){
8 | co(function *() {
9 | var response = yield fetch(Host + req.url);
10 | var mockTpl = yield response.text();
11 | res.json( mockjs.mock(safeeval(mockTpl))['data'] );
12 | });
13 | }
14 |
15 | module.exports = {
16 | 'GET /member/list': mockMapFun
17 | };
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "entry": {
4 | "index": "./src/index.js",
5 | "common": [
6 | "react"
7 | ]
8 | },
9 | "dependencies": {
10 | "antd": "^2.4.3",
11 | "dva": "^1.1.0",
12 | "html-webpack-plugin": "^2.24.1",
13 | "html-webpack-template": "^5.4.1",
14 | "merge-object": "^1.0.0",
15 | "mockjs": "^1.0.1-beta3",
16 | "object-to-formdata": "^1.0.7",
17 | "qs": "^6.3.0",
18 | "react": "^15.3.2",
19 | "react-dom": "^15.3.2",
20 | "safe-eval": "^0.3.0"
21 | },
22 | "devDependencies": {
23 | "atool-build": "^0.9.0",
24 | "atool-test-mocha": "^0.1.5",
25 | "babel-plugin-dev-expression": "^0.2.1",
26 | "babel-plugin-dva-hmr": "^0.2.0",
27 | "babel-plugin-import": "^1.1.0",
28 | "babel-plugin-transform-runtime": "^6.9.0",
29 | "babel-runtime": "^6.9.2",
30 | "co": "^4.6.0",
31 | "dora": "^0.4.3",
32 | "dora-plugin-proxy": "^0.8.4",
33 | "dora-plugin-webpack": "^0.8.1",
34 | "dora-plugin-webpack-hmr": "^0.2.1",
35 | "expect": "^1.20.2",
36 | "node-fetch": "^1.6.3",
37 | "redbox-react": "^1.3.2"
38 | },
39 | "scripts": {
40 | "start": "dora --plugins \"proxy?watchDirs=./mock,webpack,webpack-hmr\"",
41 | "build": "atool-build --hash",
42 | "test": "atool-test-mocha ./src/**/*-test.js"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/proxy.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const mock = {};
4 |
5 | require('fs').readdirSync(require('path').join(__dirname + '/mock'))
6 | .forEach(function (file) {
7 | Object.assign(mock, require('./mock/' + file));
8 | });
9 |
10 | module.exports = mock;
11 |
--------------------------------------------------------------------------------
/src/assets/yay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/que01/dva-demo/bb1d0f1ba62d378ee12e0169bd7f83accadbfb78/src/assets/yay.jpg
--------------------------------------------------------------------------------
/src/components/Example.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Example = (props) => {
4 | return (
5 |
6 | Example
7 |
8 | );
9 | };
10 |
11 | Example.propTypes = {
12 | };
13 |
14 | export default Example;
15 |
--------------------------------------------------------------------------------
/src/components/Silder.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Menu, Icon } from 'antd';
3 | import { Link } from 'dva/router'
4 | const SubMenu = Menu.SubMenu;
5 | const MenuItemGroup = Menu.ItemGroup;
6 |
7 | const Sider = React.createClass({
8 | getInitialState() {
9 | return {
10 | current: '1',
11 | };
12 | },
13 | handleClick(e) {
14 | console.log('click ', e);
15 | this.setState({
16 | current: e.key,
17 | });
18 | },
19 | render() {
20 | return (
21 |
42 | );
43 | },
44 | });
45 |
46 | export default Sider
47 |
--------------------------------------------------------------------------------
/src/components/breadcrumb.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Breadcrumb } from 'antd';
3 | import { Link } from 'dva/router'
4 | const breadcrumb = (props)=>{
5 | return (
6 |
7 | {
8 | props.data.map((v,i)=>(
9 |
10 | {v.path?({v.name}):v.name}
11 |
12 | ))
13 | }
14 |
15 | )
16 | };
17 | export default breadcrumb;
18 |
--------------------------------------------------------------------------------
/src/config/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | rapHost:'http://rap.taobao.org/mockjs/5889',
3 | rapFlag:true,
4 | onlinePath:'/api/'
5 | }
6 | export default config
7 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 |
2 | :global {
3 | html, body, #root {
4 | height: 100%;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Dva Demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './index.html';
2 | import './index.css';
3 | import dva from 'dva';
4 |
5 | // 1. Initialize
6 | const app = dva();
7 |
8 | app.model(require("./models/common"));
9 |
10 | app.model(require("./models/11"));
11 |
12 | // 2. Plugins
13 | //app.use({});
14 |
15 | // 3. Model
16 | //app.model(require('./models/example'));
17 |
18 | // 4. Router
19 | app.router(require('./router'));
20 |
21 | // 5. Start
22 | app.start('#root');
23 |
--------------------------------------------------------------------------------
/src/models/11.js:
--------------------------------------------------------------------------------
1 | import { GET } from '../utils/query'
2 | import { rapFlag, onlinePath } from '../config/config';
3 | const API = 'member/list'
4 | export default {
5 | namespace: 'test',
6 | state: {
7 | list:{
8 | data:[],
9 | loading:true,
10 | },
11 | pagination:{
12 | current:1,
13 | pageSize:10,
14 | total:null
15 | }
16 | },
17 | reducers: {
18 | fetchList(state, action) {
19 | return { ...state, ...action.payload };
20 | },
21 | },
22 | effects: {
23 | *fetchRemote({ payload }, { call, put }) {
24 | let {current,pageSize} = payload;
25 | let { data } = yield call(GET,API,{
26 | pageNum:current,
27 | pageSize:pageSize,
28 | });
29 | if (data) {
30 | yield put({
31 | type: 'fetchList',
32 | payload: {
33 | list: {
34 | data:data.results,
35 | loading:false
36 | },
37 | pagination: data.info
38 | }
39 | });
40 | }
41 | },
42 | },
43 | subscriptions: {},
44 | }
45 |
--------------------------------------------------------------------------------
/src/models/common.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespace: 'common',
3 | state: {
4 | breadcrumb:[
5 | {
6 | name:'首页',
7 | path:'/dashboard'
8 | }
9 | ]
10 | },
11 | reducers: {
12 | changeBreadcrumb(state,{ payload: breadcrumb }) {
13 | return {...state, ...breadcrumb}
14 | }
15 | },
16 | effects: {},
17 | subscriptions: {},
18 | }
19 |
--------------------------------------------------------------------------------
/src/models/example.js:
--------------------------------------------------------------------------------
1 |
2 | export default {
3 |
4 | namespace: 'example',
5 |
6 | state: {},
7 |
8 | subscriptions: {
9 | setup({ dispatch, history }) {
10 | },
11 | },
12 |
13 | effects: {
14 | *fetchRemote({ payload }, { call, put }) {
15 | },
16 | },
17 |
18 | reducers: {
19 | fetch(state, action) {
20 | return { ...state, ...action.payload };
21 | },
22 | },
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/router.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import { Router, Route, IndexRoute, Link } from 'dva/router';
3 | import IndexPage from './routes/IndexPage';
4 |
5 | const r11 = (location, callback) => {
6 | require.ensure([], require => {callback(null,
7 | require('./routes/1-1'))}, '11')
8 | };
9 | const r12 = (location, callback) => {
10 | require.ensure([], require => {callback(null,
11 | require('./routes/1-2'))}, '12')
12 | };
13 | const r21 = (location, callback) => {
14 | require.ensure([], require => {callback(null,
15 | require('./routes/2-1'))}, '21')
16 | };
17 | const r22 = (location, callback) => {
18 | require.ensure([], require => {callback(null,
19 | require('./routes/2-2'))}, '22')
20 | };
21 | const r31 = (location, callback) => {
22 | require.ensure([], require => {callback(null,
23 | require('./routes/3-1'))}, '31')
24 | };
25 | const r32 = (location, callback) => {
26 | require.ensure([], require => {callback(null,
27 | require('./routes/3-2'))}, '32')
28 | };
29 | const r33 = (location, callback) => {
30 | require.ensure([], require => {callback(null,
31 | require('./routes/3-3'))}, '33')
32 | };
33 | const r34 = (location, callback) => {
34 | require.ensure([], require => {callback(null,
35 | require('./routes/3-4'))}, '34')
36 | };
37 |
38 | export default function({ history }) {
39 | return (
40 |
41 |
42 | {/* 添加一个路由,嵌套进我们想要嵌套的 UI 里 */}
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | );
54 | };
55 |
--------------------------------------------------------------------------------
/src/routes/1-1.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'dva';
3 | import {Table,Icon} from 'antd';
4 |
5 | const columns = [
6 | {
7 | title: 'Name',
8 | dataIndex: 'name',
9 | key: 'name',
10 | render: text => {text},
11 | }, {
12 | title: 'Age',
13 | dataIndex: 'age',
14 | key: 'age',
15 | }, {
16 | title: 'Address',
17 | dataIndex: 'address',
18 | key: 'address',
19 | }, {
20 | title: 'LastLogin',
21 | dataIndex: 'lastLogin',
22 | key: 'lastLogin',
23 | }
24 | ];
25 |
26 |
27 | class Option extends React.Component{
28 | constructor(props){
29 | super(props)
30 | }
31 | render(){
32 | let {data,loading} = this.props.test.list;
33 | let pagination = this.props.test.pagination;
34 | return (
35 |
42 | )
43 | }
44 | handleTableChange(pagination, filters, sorter){
45 | this.props.dispatch({
46 | type:'test/changePage',
47 | payload:{
48 | pagination:{
49 | current:pagination.current,
50 | pageSize:pagination.pageSize,
51 | showQuickJumper: true,
52 | loading:true
53 | }
54 | }
55 | });
56 | this.fetch(pagination.current)
57 | }
58 | fetch(current){
59 | // 更新列表
60 | this.props.dispatch({
61 | type:'test/fetchRemote',
62 | payload:{
63 | current:current,
64 | pageSize:10,
65 | loading:false,
66 | }
67 | });
68 | }
69 | componentDidMount(){
70 | const breadcrumbData = {
71 | breadcrumb:[
72 | {
73 | name:'首页',
74 | path:'/'
75 | },{
76 | name:'菜单一1'
77 | }
78 | ]
79 | };
80 | this.props.dispatch({
81 | type:'common/changeBreadcrumb',
82 | payload:breadcrumbData
83 | });
84 | this.fetch(1);
85 | }
86 | }
87 | function mapStateToProps({ common,test }) {
88 | return {common,test};
89 | }
90 | export default connect(mapStateToProps)(Option);
91 |
--------------------------------------------------------------------------------
/src/routes/1-2.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'dva';
3 | class Option extends React.Component{
4 | constructor(props){
5 | super(props)
6 | }
7 | render(){
8 | return (菜单一2
)
9 | }
10 | componentDidMount(){
11 | const breadcrumbData = {
12 | breadcrumb:[
13 | {
14 | name:'首页',
15 | path:'/'
16 | },{
17 | name:'菜单一2'
18 | }
19 | ]
20 | };
21 | this.props.dispatch({
22 | type:'common/changeBreadcrumb',
23 | payload:breadcrumbData
24 | })
25 | }
26 | }
27 | function mapStateToProps({ common }) {
28 | return {common};
29 | }
30 | export default connect(mapStateToProps)(Option);
31 |
--------------------------------------------------------------------------------
/src/routes/2-1.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'dva';
3 | class Option extends React.Component{
4 | constructor(props){
5 | super(props)
6 | }
7 | render(){
8 | return (菜单二1
)
9 | }
10 | componentDidMount(){
11 | const breadcrumbData = {
12 | breadcrumb:[
13 | {
14 | name:'首页',
15 | path:'/'
16 | },{
17 | name:'菜单二1'
18 | }
19 | ]
20 | };
21 | this.props.dispatch({
22 | type:'common/changeBreadcrumb',
23 | payload:breadcrumbData
24 | })
25 | }
26 | }
27 | function mapStateToProps({ common }) {
28 | return {common};
29 | }
30 | export default connect(mapStateToProps)(Option);
31 |
--------------------------------------------------------------------------------
/src/routes/2-2.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'dva';
3 | class Option extends React.Component{
4 | constructor(props){
5 | super(props)
6 | }
7 | render(){
8 | return (菜单二2
)
9 | }
10 | componentDidMount(){
11 | const breadcrumbData = {
12 | breadcrumb:[
13 | {
14 | name:'首页',
15 | path:'/'
16 | },{
17 | name:'菜单二2'
18 | }
19 | ]
20 | };
21 | this.props.dispatch({
22 | type:'common/changeBreadcrumb',
23 | payload:breadcrumbData
24 | })
25 | }
26 | }
27 | function mapStateToProps({ common }) {
28 | return {common};
29 | }
30 | export default connect(mapStateToProps)(Option);
31 |
--------------------------------------------------------------------------------
/src/routes/3-1.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'dva';
3 | class Option extends React.Component{
4 | constructor(props){
5 | super(props)
6 | }
7 | render(){
8 | return (菜单三1
)
9 | }
10 | componentDidMount(){
11 | const breadcrumbData = {
12 | breadcrumb:[
13 | {
14 | name:'首页',
15 | path:'/'
16 | },{
17 | name:'菜单三1'
18 | }
19 | ]
20 | };
21 | this.props.dispatch({
22 | type:'common/changeBreadcrumb',
23 | payload:breadcrumbData
24 | })
25 | }
26 | }
27 | function mapStateToProps({ common }) {
28 | return {common};
29 | }
30 | export default connect(mapStateToProps)(Option);
31 |
--------------------------------------------------------------------------------
/src/routes/3-2.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'dva';
3 | class Option extends React.Component{
4 | constructor(props){
5 | super(props)
6 | }
7 | render(){
8 | return (菜单三2
)
9 | }
10 | componentDidMount(){
11 | const breadcrumbData = {
12 | breadcrumb:[
13 | {
14 | name:'首页',
15 | path:'/'
16 | },{
17 | name:'菜单三2'
18 | }
19 | ]
20 | };
21 | this.props.dispatch({
22 | type:'common/changeBreadcrumb',
23 | payload:breadcrumbData
24 | })
25 | }
26 | }
27 | function mapStateToProps({ common }) {
28 | return {common};
29 | }
30 | export default connect(mapStateToProps)(Option);
31 |
--------------------------------------------------------------------------------
/src/routes/3-3.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'dva';
3 | class Option extends React.Component{
4 | constructor(props){
5 | super(props)
6 | }
7 | render(){
8 | return (菜单三3
)
9 | }
10 | componentDidMount(){
11 | const breadcrumbData = {
12 | breadcrumb:[
13 | {
14 | name:'首页',
15 | path:'/'
16 | },{
17 | name:'菜单三3'
18 | }
19 | ]
20 | };
21 | this.props.dispatch({
22 | type:'common/changeBreadcrumb',
23 | payload:breadcrumbData
24 | })
25 | }
26 | }
27 | function mapStateToProps({ common }) {
28 | return {common};
29 | }
30 | export default connect(mapStateToProps)(Option);
31 |
--------------------------------------------------------------------------------
/src/routes/3-4.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'dva';
3 | class Option extends React.Component{
4 | constructor(props){
5 | super(props)
6 | }
7 | render(){
8 | return (菜单三4
)
9 | }
10 | componentDidMount(){
11 | const breadcrumbData = {
12 | breadcrumb:[
13 | {
14 | name:'首页',
15 | path:'/'
16 | },{
17 | name:'菜单三4'
18 | }
19 | ]
20 | };
21 | this.props.dispatch({
22 | type:'common/changeBreadcrumb',
23 | payload:breadcrumbData
24 | })
25 | }
26 | }
27 | function mapStateToProps({ common }) {
28 | return {common};
29 | }
30 | export default connect(mapStateToProps)(Option);
31 |
--------------------------------------------------------------------------------
/src/routes/IndexPage.css:
--------------------------------------------------------------------------------
1 |
2 | .normal {
3 | font-family: Georgia, sans-serif;
4 | margin-top: 3em;
5 | text-align: center;
6 | }
7 |
8 | .title {
9 | font-size: 2.5rem;
10 | font-weight: normal;
11 | letter-spacing: -1px;
12 | }
13 |
14 | .welcome {
15 | height: 328px;
16 | background: url(../assets/yay.jpg) no-repeat center 0;
17 | background-size: 388px 328px;
18 | }
19 |
20 | .list {
21 | font-size: 1.2em;
22 | margin-top: 1.8em;
23 | list-style: none;
24 | line-height: 1.5em;
25 | }
26 |
27 | .list code {
28 | background: #f7f7f7;
29 | }
30 |
--------------------------------------------------------------------------------
/src/routes/IndexPage.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import { connect } from 'dva';
3 | import { Link } from 'dva/router';
4 | import styles from './IndexPage.css';
5 |
6 | import Silder from '../components/Silder'
7 | import CustomBreadcrumb from '../components/breadcrumb'
8 |
9 | import { Row, Col } from 'antd';
10 |
11 | const breadcrumbData = [
12 | {
13 | name:'首页',
14 | path:'/'
15 | },{
16 | name:'菜单21',
17 | path:'/21'
18 | }
19 | ];
20 |
21 | class App extends Component {
22 | constructor(props){
23 | super(props)
24 | }
25 | render(){
26 | return(
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | {this.props.children||'内容区域'}
36 |
37 |
38 | )
39 | }
40 | }
41 |
42 | function mapStateToProps({ common }) {
43 | return {common};
44 | }
45 | export default connect(mapStateToProps)(App);
46 |
--------------------------------------------------------------------------------
/src/services/example.js:
--------------------------------------------------------------------------------
1 | import request from '../utils/request';
2 |
3 | export async function query() {
4 | return request('/api/users');
5 | }
6 |
--------------------------------------------------------------------------------
/src/tests/models/example-test.js:
--------------------------------------------------------------------------------
1 | import expect from 'expect';
2 | import example from '../../models/example';
3 |
4 | describe('example', () => {
5 |
6 | describe('reducer', () => {
7 | it('it should save', () => {
8 | expect(example.reducers['example/save']({}, { payload: { a: 1 }})).toEqual({ a: 1 });
9 | });
10 | })
11 | });
12 |
--------------------------------------------------------------------------------
/src/utils/query.js:
--------------------------------------------------------------------------------
1 | import request from '../utils/request';
2 | import qs ,{ parse } from 'qs';
3 | import FormdataWrapper from 'object-to-formdata';
4 | import merge from 'merge-object';
5 | import {rapHost, onlinePath} from '../config/config'
6 |
7 | const cookieTrue = {
8 | credentials: 'include'
9 | };
10 | const jsonConf = {
11 | headers: {
12 | 'Content-Type': 'application/json'
13 | }
14 | }
15 |
16 | function getUrl(smarturl,flag) {
17 | if(flag){
18 | return rapHost + '/' + smarturl;
19 | }else{
20 | return onlinePath + smarturl;
21 | }
22 | }
23 |
24 | async function POST(url,params,isJson){
25 | if(isJson == undefined){isJson = false};
26 | return request( url,merge({
27 | method: 'POST',
28 | body:isJson?JSON.stringify(params):FormdataWrapper(params),
29 | },isJson?merge(jsonConf,cookieTrue):cookieTrue),rapFlag);
30 | }
31 |
32 | async function GET(url,params){
33 | return request( url + `?${qs.stringify(params)}`,merge({
34 | method: 'GET',
35 | },cookieTrue));
36 | }
37 |
38 | export {
39 | POST,GET
40 | }
41 |
--------------------------------------------------------------------------------
/src/utils/request.js:
--------------------------------------------------------------------------------
1 | import fetch from 'dva/fetch';
2 | import safeeval from 'safe-eval'
3 | import Mock from 'mockjs';
4 |
5 | function parseText(response) {
6 | return response.json();
7 | }
8 |
9 | function checkStatus(response) {
10 | if (response.status >= 200 && response.status < 300) {
11 | return response;
12 | }
13 | const error = new Error(response.statusText);
14 | error.response = response;
15 | throw error;
16 | }
17 |
18 | /**
19 | * Requests a URL, returning a promise.
20 | *
21 | * @param {string} url The URL we want to request
22 | * @param {object} [options] The options we want to pass to "fetch"
23 | * @return {object} An object containing either "data" or "err"
24 | */
25 | export default function request(url, options) {
26 | return fetch(url, options)
27 | .then(checkStatus)
28 | .then(parseText)
29 | .then((data) => ({ data }))
30 | .catch((err) => ({ err }));
31 | }
32 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('atool-build/lib/webpack');
2 | const HtmlWebpackPlugin = require('html-webpack-plugin');
3 |
4 | module.exports = function(webpackConfig, env) {
5 | webpackConfig.babel.plugins.push('transform-runtime');
6 |
7 | // Support hmr
8 | if (env === 'development') {
9 | webpackConfig.devtool = '#eval';
10 | webpackConfig.babel.plugins.push('dva-hmr');
11 | } else {
12 | webpackConfig.babel.plugins.push('dev-expression');
13 | webpackConfig.plugins.push(
14 | new HtmlWebpackPlugin({
15 | inject: false,
16 | template: require('html-webpack-template'),
17 | title: 'Dva Demo',
18 | appMountId: 'root',
19 | minify: {
20 | removeComments: true,
21 | collapseWhitespace: true
22 | },
23 | links:['//at.alicdn.com/t/font_xxxxxxxx.css']
24 | })
25 | );
26 | }
27 |
28 | // Don't extract common.js and common.css
29 | webpackConfig.plugins = webpackConfig.plugins.filter(function(plugin) {
30 | return !(plugin instanceof webpack.optimize.CommonsChunkPlugin);
31 | });
32 |
33 | // Support CSS Modules
34 | // Parse all less files as css module.
35 | webpackConfig.module.loaders.forEach(function(loader, index) {
36 | if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.less$') > -1) {
37 | loader.include = /node_modules/;
38 | loader.test = /\.less$/;
39 | }
40 | if (loader.test.toString() === '/\\.module\\.less$/') {
41 | loader.exclude = /node_modules/;
42 | loader.test = /\.less$/;
43 | }
44 | if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.css$') > -1) {
45 | loader.include = /node_modules/;
46 | loader.test = /\.css$/;
47 | }
48 | if (loader.test.toString() === '/\\.module\\.css$/') {
49 | loader.exclude = /node_modules/;
50 | loader.test = /\.css$/;
51 | }
52 | });
53 |
54 | webpackConfig.babel.plugins.push(['import', {
55 | libraryName: 'antd',
56 | style: 'css',
57 | }]);
58 |
59 | return webpackConfig;
60 | };
61 |
--------------------------------------------------------------------------------