├── .babelrc ├── .gitignore ├── README.md ├── _config.yml ├── components ├── ChildPage │ ├── index.js │ └── index.less ├── HomePage │ ├── index.js │ └── index.less ├── NestedRouter │ ├── index.js │ └── index.less └── StructChart │ ├── index.js │ ├── index.less │ └── treeConfig.js ├── helpers └── with-mobx-store.js ├── next.config.js ├── nodemon.json ├── package-lock.json ├── package.json ├── pages ├── _app.js ├── _document.js ├── demo.js ├── index.js ├── nestedRouter │ ├── index.js │ ├── index.less │ ├── link1 │ │ └── index.js │ └── link2 │ │ └── index.js ├── netWork.js └── structChart.js ├── postcss.config.js ├── routers └── index.js ├── server.js ├── static ├── css │ └── antd.min.css ├── images │ ├── Screenshot from 2019-04-22 11-51-34.png │ ├── Screenshot from 2019-04-22 11-51-48.png │ ├── antd.png │ ├── mobx.png │ └── next.png ├── manifest.json └── manifest │ └── icon │ └── favicon-32x32.png ├── store ├── appStore.js └── index.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "next/babel" 4 | ], 5 | "plugins": [ 6 | ["@babel/plugin-proposal-decorators", { "legacy": true }], 7 | ["@babel/plugin-proposal-class-properties", { "loose": true }] 8 | ] 9 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .next/ 2 | node_modules/ 3 | .vscode/ 4 | out 5 | .idea/ 6 | yarn.lock 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 图片 3 | 图片 4 | 图片 5 |

6 | 7 | Next.js是服务端渲染呈现的React应用程序的简约框架,这个项目通过配置Next.js+Mbox实现的一个Demo. 8 | 9 | ## 模块 10 | 11 | + react-helmet 12 | + mobx v5.0.3 13 | + next 14 | + less 15 | + Express v4.16.3 16 | + React v16.4.2 17 | + next-routes 18 | + antd v3.9.2 19 | 20 | ## 预览图 21 |

22 | 图片 23 | 图片 24 |

25 | 26 | 27 | ## 功能 28 | 29 | + 服务端渲染 30 | + js按需加载 31 | + Mobx状态管理器 32 | 33 | ## 其它 34 | 35 | ### 使用了动态路由跳转使用next-routes提供的方法 36 | 37 | #### 路由声明`routers/index.js` 38 | 39 | ```js 40 | const routes = require('next-routes'); 41 | 42 | module.exports = routes() 43 | .add('demo', '/demo/:id', 'demo') 44 | .add('nestedRouter', '/nested_router', 'nestedRouter') 45 | .add('link1', '/nested_router/link1', 'nestedRouter/link1') 46 | .add('link2', '/nested_router/link2', 'nestedRouter/link2') 47 | .add('netWork', '/netWork', 'netWork') 48 | .add('structChart', '/struct_chart', 'structChart') 49 | ``` 50 | 51 | #### 使用`Link`路由跳转 52 | 53 | ```js 54 | import {Link} from '../routes' 55 | 56 | export default () => ( 57 |
58 |
Welcome to Next.js!
59 | 60 | Hello world 61 | 62 | 或者 63 | 64 | Hello world 65 | 66 |
67 | ) 68 | ``` 69 | #### 使用`Router`跳转路由 70 | 71 | ```js 72 | import React from 'react' 73 | import {Router} from '../routes' 74 | 75 | export default class Blog extends React.Component { 76 | handleClick () { 77 | // With route name and params 78 | Router.pushRoute('blog', {slug: 'hello-world'}) 79 | // With route URL 80 | Router.pushRoute('/blog/hello-world') 81 | } 82 | render () { 83 | return ( 84 |
85 |
{this.props.url.query.slug}
86 | 87 |
88 | ) 89 | } 90 | } 91 | ``` 92 | ## 如何使用 93 | 94 | ### 安装 95 | 96 | ```bash 97 | npm install 或 yarn(推荐) 98 | ``` 99 | ### 开发环境运行 100 | ```bash 101 | npm run dev 102 | ``` 103 | ### 产品环境运行 104 | ```bash 105 | npm start 106 | ``` 107 | ### 打包HTML静态文件 108 | ```bash 109 | npm run biuld 110 | ``` -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /components/ChildPage/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from '../../routers'; 3 | import { inject, observer } from 'mobx-react'; 4 | import { toJS } from 'mobx'; 5 | import styles from './index.less'; 6 | 7 | function ChildPage({ appStore }) { 8 | console.log(toJS(appStore.treeData), appStore.name, '-----------'); 9 | return( 10 | 11 | 12 | 首页 13 | 14 |

子页面{ appStore.name }

15 |
16 | ) 17 | } 18 | 19 | export default inject('appStore')(observer(ChildPage)); -------------------------------------------------------------------------------- /components/ChildPage/index.less: -------------------------------------------------------------------------------- 1 | .text { 2 | font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; 3 | } 4 | .link { 5 | color: #000000; 6 | &:hover { 7 | color: #4c4c4c; 8 | } 9 | } -------------------------------------------------------------------------------- /components/HomePage/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import cowsay from 'cowsay-browser'; 3 | import styles from './index.less'; 4 | import { observer, inject } from 'mobx-react'; 5 | import { Button } from 'antd'; 6 | import { toJS } from 'mobx'; 7 | import { Router } from '../../routers'; 8 | 9 | function HomePage({ homeStore, appStore }) { 10 | return ( 11 | 12 |

Hello World!{homeStore.name}

13 | 14 |    15 | 16 |
17 |                 {cowsay.say({ text: 'hi there!' })}
18 |             
19 |

{appStore.name}

20 | 25 |
26 | ); 27 | } 28 | 29 | export default inject('homeStore', 'appStore')(observer(HomePage)); -------------------------------------------------------------------------------- /components/HomePage/index.less: -------------------------------------------------------------------------------- 1 | @font-size: 20px; 2 | .title { 3 | font-size: @font-size; 4 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 5 | &:hover { 6 | text-decoration: underline; 7 | } 8 | } 9 | 10 | .click { 11 | cursor: pointer; 12 | &:hover { 13 | text-decoration: underline; 14 | } 15 | } -------------------------------------------------------------------------------- /components/NestedRouter/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './index.less'; 3 | import { Router } from '../../routers'; 4 | import { observer, inject } from 'mobx-react'; 5 | 6 | function HomePage({ children, homeStore }) { 7 | return ( 8 | 9 |

嵌套路由!{homeStore.name}

10 |

{Router.pushRoute('link1')}}>子路由1

11 |

{Router.pushRoute('link2')}}>子路由2

12 | { children } 13 |
14 | ); 15 | } 16 | 17 | export default inject('homeStore')(observer(HomePage)); -------------------------------------------------------------------------------- /components/NestedRouter/index.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tecode/next_react/c9df05307145854e4a934af0e454674e72e0595d/components/NestedRouter/index.less -------------------------------------------------------------------------------- /components/StructChart/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Helmet from 'react-helmet'; 3 | import TREE from './treeConfig'; 4 | import styles from './index.less'; 5 | 6 | let svg; 7 | let container; 8 | 9 | 10 | class StructChart extends Component { 11 | constructor() { 12 | super(); 13 | this.state = { 14 | chartDom: '#structChart', 15 | data: { 16 | companyName: '重庆渝宁化肥有限公司', 17 | dataType: 1, 18 | eid: 'root', 19 | entinvInfo: [], 20 | frInfo: [{ 21 | color: 'green', 22 | conDate: '2011-06-15', 23 | dataType: 1, 24 | direction: 'bottom', 25 | eid: 'a6937a5b-98bc-4052-9d32-1f8f7e57b137', 26 | fundedRatio: '0.4000', 27 | id: 5, 28 | identifier: 'fff866ee-607e-4577-bd87-8786e0d780a5', 29 | idx: 0, 30 | isNeedExtends: false, 31 | isStock: false, 32 | loading: false, 33 | name: '重庆长宏农资有限公司', 34 | num: null, 35 | position: null, 36 | regCapCur: '人民币', 37 | scale: null, 38 | sign: 'frInfo', 39 | structureIndex: 0, 40 | subConam: '20.000000', 41 | treeInfo: { 42 | date: '出资日期: 2011-06-15', 43 | invest: '投资: 20.00万元', 44 | isFr: false, 45 | ratio: '占比: 40.00%', 46 | treeKey: 'name', 47 | treename: '重庆长宏农资有限公司', 48 | x0: 0, 49 | y0: 230, 50 | _subName: '司', 51 | } 52 | }], 53 | identifier: 'root', 54 | shareInfo: [ 55 | { 56 | color: 'orange', 57 | conDate: '2010-12-20', 58 | dataType: 2, 59 | direction: 'top', 60 | eid: '799e28e7-aced-4584-a3f0-8b6eabeb4434', 61 | fundedRatio: '0.800000', 62 | id: 2, 63 | identifier: '6c0cf36e-509a-4407-aae1-30721eae97e6', 64 | idx: 0, 65 | isNeedExtends: false, 66 | isStock: false, 67 | loading: false, 68 | name: '张长蓉', 69 | num: null, 70 | position: null, 71 | regCapCur: '人民币', 72 | scale: null, 73 | structureIndex: 0, 74 | subConam: '320.000000', 75 | treeInfo: { 76 | date: '出资日期: 2010-12-20', 77 | invest: '投资: 320.00万元', 78 | isFr: false, 79 | ratio: '占比: 80.00%', 80 | }, 81 | treeKey: 'name', 82 | treename: '张长蓉', 83 | x0: -75, 84 | y0: 0, 85 | _layerIndex: -1, 86 | _selector: '.hover-link-6c0cf36e-509a-4407-aae1-30721eae97e6,.border-6c0cf36e-509a-4407-aae1-30721eae97e6', 87 | }, 88 | { 89 | color: 'orange', 90 | conDate: '2010-12-20', 91 | dataType: 2, 92 | direction: 'top', 93 | eid: '8e5f4895-6a4b-48e3-9663-785e9a269a83', 94 | fundedRatio: '0.200000', 95 | id: 3, 96 | identifier: '1c592d45-4262-48c0-bfe0-8d5f2a008e40', 97 | idx: 1, 98 | isNeedExtends: false, 99 | isStock: false, 100 | loading: false, 101 | name: '胡贤玲', 102 | num: null, 103 | position: null, 104 | regCapCur: '人民币', 105 | scale: null, 106 | structureIndex: 1, 107 | subConam: '80.000000', 108 | treeInfo: { 109 | date: '出资日期: 2010-12-20', 110 | invest: '投资: 80.00万元', 111 | isFr: false, 112 | ratio: '占比: 20.00%', 113 | }, 114 | treeKey: 'name', 115 | treename: '胡贤玲', 116 | x0: 75, 117 | y0: 0, 118 | _layerIndex: -1, 119 | _selector: '.hover-link-1c592d45-4262-48c0-bfe0-8d5f2a008e40,.border-1c592d45-4262-48c0-bfe0-8d5f2a008e40', 120 | } 121 | ] 122 | } 123 | } 124 | } 125 | // 创建SVGDOM节点 126 | initSvgDom = (svgWidth, _svgHeight) => { 127 | // d3.select(this.state.chartDom).select('svg').remove(); 128 | svg = d3.select(this.state.chartDom) 129 | .append('svg:svg') 130 | .attr('width', svgWidth) 131 | .attr('height', _svgHeight) 132 | .attr('id', 'structureChart') 133 | .style('transition', `height ${TREE.transitionTime}ms ease-in-out`) 134 | .classed('new-network-rect', true); 135 | // 添加LOGO 136 | // logo = svg.append('svg:g').attr('id', 'structureChartLogo').style('transition', `height ${TREE.transitionTime}ms ease-in-out`).html(this.logSVG); 137 | // 标记区 138 | svg.append('defs').append('marker') 139 | .attr('id', 'arrow') 140 | .attr('viewBox', '0 0 10 10') 141 | .attr('markerUnits', 'strokeWidth') 142 | .attr('refX', 10) 143 | .attr('refY', 5) 144 | .attr('markerWidth', 20) 145 | .attr('markerHeight', 20) 146 | .attr('orient', 'auto').append('path') 147 | .attr('d', 'M4,2 L10,5 L4,8 L4,2') 148 | .attr('fill', TREE.arrow); 149 | svg.append('defs').append('marker') 150 | .attr('id', 'arrowBlue') 151 | .attr('viewBox', '0 0 10 10') 152 | .attr('markerUnits', 'strokeWidth') 153 | .attr('refX', 10) 154 | .attr('refY', 5) 155 | .attr('markerWidth', 20) 156 | .attr('markerHeight', 20) 157 | .attr('orient', 'auto') 158 | .append('path') 159 | .attr('d', 'M4,2 L10,5 L4,8 L4,2') 160 | .attr('fill', TREE.arrowBlue); 161 | svg.append('defs').append('marker') 162 | .attr('id', 'arrowGreen') 163 | .attr('viewBox', '0 0 10 10') 164 | .attr('markerUnits', 'strokeWidth') 165 | .attr('refX', 10) 166 | .attr('refY', 5) 167 | .attr('markerWidth', 20) 168 | .attr('markerHeight', 20) 169 | .attr('orient', 'auto') 170 | .append('path') 171 | .attr('d', 'M4,2 L10,5 L4,8 L4,2') 172 | .attr('fill', TREE.arrowGreen); 173 | svg.append('defs').append('marker') 174 | .attr('id', 'arrowOrange') 175 | .attr('viewBox', '0 0 10 10') 176 | .attr('markerUnits', 'strokeWidth') 177 | .attr('refX', 10) 178 | .attr('refY', 5) 179 | .attr('markerWidth', 20) 180 | .attr('markerHeight', 20) 181 | .attr('orient', 'auto') 182 | .append('path') 183 | .attr('d', 'M4,2 L10,5 L4,8 L4,2') 184 | .attr('fill', TREE.arrowOrange); 185 | // 内容区 186 | container = svg.append('svg:g') 187 | .attr('id', 'structureChartContainer'); 188 | // 根节点区 189 | container.append('svg:g') 190 | .classed('centerG', true).style('transition', `transform ${TREE.transitionTime}ms ease-in-out`); 191 | 192 | // 顶部数据区 193 | this.topGroup = container.append('svg:g') 194 | .classed('topG', true).style('transition', `transform ${TREE.transitionTime}ms ease-in-out`); 195 | this.topGroup.append('svg:g').classed('topGLinks', true); 196 | this.topGroup.append('svg:g').classed('topGHoverLinks', true); 197 | this.topGroup.append('svg:g').classed('topGNodes', true); 198 | 199 | // 底部数据区 200 | this.bottomGroup = container.append('svg:g') 201 | .classed('bottomG', true).style('transition', `transform ${TREE.transitionTime}ms ease-in-out`); 202 | this.bottomGroup.append('svg:g').classed('bottomGLinks', true); 203 | this.bottomGroup.append('svg:g').classed('bottomGHoverLinks', true); 204 | this.bottomGroup.append('svg:g').classed('bottomGNodes', true); 205 | }; 206 | componentDidMount() { 207 | this.initSvgDom('100%', 600); 208 | } 209 | render() { 210 | return ( 211 | 212 | 213 | My Title 214 | 215 | 216 |
217 |
218 | ); 219 | } 220 | } 221 | 222 | export default StructChart; -------------------------------------------------------------------------------- /components/StructChart/index.less: -------------------------------------------------------------------------------- 1 | .wrap { 2 | position: relative; 3 | cursor: move; 4 | } 5 | // 低版本谷歌浏览器缩放不兼容 6 | svg { 7 | text-rendering: geometricPrecision 8 | } 9 | .nodeTwinkle { 10 | animation: animations-twinkle 2s ease infinite; 11 | } 12 | 13 | @keyframes animations-twinkle { 14 | 0% { 15 | stroke-width: 0; 16 | stroke-opacity: 1 17 | } 18 | to { 19 | stroke-width: 10px; 20 | stroke-opacity: 0 21 | } 22 | } 23 | @keyframes animations-loading { 24 | 0% { 25 | transform: rotate(0deg); 26 | } 27 | to { 28 | transform: rotate(360deg); 29 | } 30 | } 31 | .verticalLineLoadding { 32 | animation: animations-loading 1s ease infinite 33 | } 34 | 35 | :global { 36 | .new-network-rect { 37 | cursor: move 38 | } 39 | @keyframes animations { 40 | 0% { 41 | stroke-width: 0; 42 | stroke-opacity: 1 43 | } 44 | to { 45 | stroke-width: 10px; 46 | stroke-opacity: 0 47 | } 48 | } 49 | .new-network-node-twinkle { 50 | animation: animations 2s ease infinite 51 | } 52 | 53 | .structure-border.blue.active, 54 | .structure-link.blue.active, 55 | .structure-hover-link.blue.active, 56 | .structure-marker.blue.active { 57 | stroke: #42A5F5 !important; 58 | } 59 | .structure-border.green.active, 60 | .structure-link.green.active, 61 | .structure-hover-link.green.active, 62 | .structure-marker.green.active { 63 | stroke: #66BB6A !important; 64 | } 65 | .structure-border.orange.active, 66 | .structure-link.orange.active, 67 | .structure-hover-link.orange.active, 68 | .structure-marker.orange.active { 69 | stroke: #FF9800 !important; 70 | } 71 | } 72 | 73 | .boxFullScreen { 74 | position: fixed; 75 | top: 0; 76 | left: 0; 77 | right: 0; 78 | bottom: 0; 79 | z-index: 1400; 80 | background-color: #fff; 81 | } 82 | -------------------------------------------------------------------------------- /components/StructChart/treeConfig.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // 通用样式设置 3 | strokeLineColor: '#E0E0E0', /* 连接线颜色 */ 4 | strokeLineWidth: 1, /* 连接线宽度 */ 5 | transitionTime: 400, /* 过渡时间 */ 6 | openBtnRadius: 7, /* 展开按钮半径 */ 7 | svgPadding: 100, /* 图形上下的边距 */ 8 | svgSDKPadding: 20, /* 图形上下的边距 */ 9 | 10 | // 连接线颜色(less产生) 11 | strokeLineBlueColor: '#42A5F5', /* 蓝色边线颜色 */ // less 12 | strokeLineOrangeColor: '#FF9800', /* 橙色边线颜色 */ // less 13 | strokeLineGreenColor: '#66BB6A', /* 绿色边线颜色 */ // less 14 | // 箭头颜色 15 | arrow: '#E0E0E0', /* 普通箭头颜色 */ 16 | arrowBlue: '#42A5F5', /* 蓝色箭头颜色 */ 17 | arrowOrange: '#FF9800', /* 橙色箭头颜色 */ 18 | arrowGreen: '#66BB6A', /* 绿色箭头颜色 */ 19 | arrowTopMargin: 15, /* 顶部箭头外边距 */ 20 | arrowBottomMargin: 10, /* 底部箭头外边距 */ 21 | // 节点样式 22 | nodeLineColor: '#E0E0E0', /* 节点边线颜色 */ 23 | nodeBottomLineBlue: '#42A5F5', /* 蓝色节点底线颜色 */ 24 | nodeBottomLineOrange: '#FF9800', /* 橙色节点底线颜色 */ 25 | nodeBottomLineGreen: '#66BB6A', /* 绿色节点底线颜色 */ 26 | nodeBgColor: '#FFFFFF', /* 节点背景颜色 */ 27 | strokeNodeColor: '#E0E0E0', /* 节点边线颜色 */ 28 | nodeLineWidth: 1, /* 节点边线宽度 */ 29 | rootNodeHeight: 40, /* 根节点高度 */ 30 | rootTitleNodeFontSize: 16, /* 根节点标题字体大小 */ 31 | nodeTitleFontSize: 13, /* 子节点标题字体大小 */ 32 | nodeContentTopPadding: 7, /* 子节点内容和标题间距 */ 33 | nodeContentPadding: 5, /* 子节点内容间距 */ 34 | nodeContentFontSize: 12, /* 子节点内容字体大小 */ 35 | nodePadding: 10, /* 节点内边距 */ 36 | nodeSizeX: 150, /* 节点X尺寸[x, y], 调节各节点之间的宽度 */ 37 | nodeSizeY: 230, /* 节点Y尺寸[x, y], 调节各层级之间的高度 */ 38 | nodeWidth: 135, /* 子节点宽度 */ 39 | nodeHeight: 90, /* 子节点高度 */ 40 | nodeBottomTitlePadding: 6, /* 下方子节点标题内边距 */ 41 | nodeBottomHeight: 93, /* 下方子节点高度 */ 42 | nodeRx: 0, /* 子节点圆角幅度 */ 43 | nodeBottomLineHeight: 2, /* 节点底线高度 */ 44 | // 标签样式 45 | tagHeight: 20, /* 标签高度 */ 46 | tagWidth: 57, /* 标签宽度 */ 47 | tagPadding: 4, /* 标签内边距 */ 48 | tagRx: 2, /* 标签节点圆角幅度 */ 49 | tagColor: '#FFFFFF', /* 标签颜色 */ 50 | tagBlueColor: '#42A5F5', /* 蓝色标签 */ 51 | tagOrangeColor: '#FF9800', /* 橙色标签 */ 52 | tagGreenColor: '#66BB6A', /* 绿色标签 */ 53 | // 节点文本样式 54 | nodeTitleColor: '#000000', /* 节点文本标题颜色 */ 55 | nodeContentColor: '#424242', /* 节点普通内容颜色 */ 56 | nodeContentBlueColor: '#42A5F5', /* 节点蓝色内容颜色 */ 57 | nodeContentOrangeColor: '#FF9800', /* 节点橙色内容颜色 */ 58 | nodeContentGreenColor: '#66BB6A', /* 节点绿色内容颜色 */ 59 | }; 60 | -------------------------------------------------------------------------------- /helpers/with-mobx-store.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { initializeStore } from '../store' 3 | 4 | const isServer = typeof window === 'undefined' 5 | const __NEXT_MOBX_STORE__ = '__NEXT_MOBX_STORE__' 6 | 7 | function getOrCreateStore(initialState) { 8 | // Always make a new store if server, otherwise state is shared between requests 9 | if (isServer) { 10 | return initializeStore(initialState) 11 | } 12 | 13 | // Create store if unavailable on the client and set it on the window object 14 | if (!window[__NEXT_MOBX_STORE__]) { 15 | window[__NEXT_MOBX_STORE__] = initializeStore(initialState) 16 | } 17 | return window[__NEXT_MOBX_STORE__] 18 | } 19 | 20 | export default (App) => { 21 | return class AppWithMobx extends React.Component { 22 | static async getInitialProps (appContext) { 23 | // Get or Create the store with `undefined` as initialState 24 | // This allows you to set a custom default initialState 25 | const mobxStore = getOrCreateStore() 26 | 27 | // Provide the store to getInitialProps of pages 28 | appContext.ctx.mobxStore = mobxStore 29 | 30 | let appProps = {} 31 | if (typeof App.getInitialProps === 'function') { 32 | appProps = await App.getInitialProps.call(App, appContext) 33 | } 34 | 35 | return { 36 | ...appProps, 37 | ...mobxStore 38 | } 39 | } 40 | 41 | constructor(props) { 42 | super(props) 43 | this.mobxStore = getOrCreateStore(props.initialMobxState) 44 | } 45 | 46 | render() { 47 | return 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | // next.config.js 2 | const withLess = require('@zeit/next-less'); 3 | 4 | module.exports = withLess({ 5 | cssModules: true, 6 | cssLoaderOptions: { 7 | importLoaders: 1, 8 | localIdentName: "[local]___[hash:base64:5]", 9 | }, 10 | webpack: config => { 11 | // Fixes npm packages that depend on `fs` module 12 | config.node = { 13 | fs: 'empty' 14 | }; 15 | 16 | return config; 17 | } 18 | }) -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": true, 3 | "ignore": ["node_modules", ".next"], 4 | "watch": [ 5 | "server.js", 6 | "store/" 7 | ], 8 | "ext": "js json" 9 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next_react", 3 | "version": "1.2.1", 4 | "description": "A Next Project", 5 | "main": "server.js", 6 | "dependencies": { 7 | "@zeit/next-css": "^1.0.1", 8 | "@zeit/next-less": "^1.0.1", 9 | "antd": "^3.9.2", 10 | "babel-plugin-transform-class-properties": "^6.24.1", 11 | "babel-plugin-transform-decorators-legacy": "^1.3.5", 12 | "cowsay-browser": "^1.1.8", 13 | "express": "^4.16.3", 14 | "less": "^3.8.1", 15 | "mobx": "^5.0.3", 16 | "mobx-react": "^5.2.5", 17 | "next": "^7.0.0", 18 | "next-routes": "^1.4.2", 19 | "react": "^16.6.7", 20 | "react-dom": "^16.4.2", 21 | "react-helmet": "^5.2.0" 22 | }, 23 | "devDependencies": { 24 | "@babel/plugin-proposal-class-properties": "^7.1.0", 25 | "@babel/plugin-proposal-decorators": "^7.1.0", 26 | "nodemon": "^1.18.3", 27 | "postcss-css-variables": "^0.9.0", 28 | "lodash": ">=4.17.11" 29 | }, 30 | "scripts": { 31 | "dev": "nodemon server.js", 32 | "build": "next build && next export", 33 | "start": "NODE_ENV=production node server.js", 34 | "test": "echo \"Error: no test specified\" && exit 1" 35 | }, 36 | "keywords": [ 37 | "next", 38 | "react" 39 | ], 40 | "author": "", 41 | "license": "ISC" 42 | } 43 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import App, {Container} from 'next/app'; 2 | import React from 'react'; 3 | import withMobxStore from '../helpers/with-mobx-store'; 4 | import { Provider } from 'mobx-react'; 5 | 6 | class MyApp extends App { 7 | render () { 8 | const {Component, pageProps, allStore} = this.props 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ) 16 | } 17 | } 18 | 19 | export default withMobxStore(MyApp) -------------------------------------------------------------------------------- /pages/_document.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Document, { Main, NextScript } from 'next/document'; 3 | import Head from 'next/head'; 4 | 5 | export default class MyDocument extends Document { 6 | render() { 7 | // console.log(this.props.buildManifest.pages, '----------------------->>>>>>>>>>>'); 8 | return ( 9 | 10 | 11 | 12 | Next_Project 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | ) 23 | } 24 | } -------------------------------------------------------------------------------- /pages/demo.js: -------------------------------------------------------------------------------- 1 | import ChildPage from '../components/ChildPage'; 2 | import Head from 'next/head'; 3 | 4 | export default () => ( 5 | 6 | 7 | 8 | Child-Next-React 9 | 10 | 11 | ); -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import HomePage from '../components/HomePage'; 2 | import Head from 'next/head'; 3 | 4 | export default () => ( 5 | 6 | 7 | 8 | Home-Next-React 9 | 10 | 11 | 12 | ); -------------------------------------------------------------------------------- /pages/nestedRouter/index.js: -------------------------------------------------------------------------------- 1 | import { Helmet } from "react-helmet"; 2 | import Body from '../../components/NestedRouter'; 3 | 4 | export default (props) => ( 5 | 6 | 7 | 8 | 嵌套路由 9 | 10 | 5 11 | ); -------------------------------------------------------------------------------- /pages/nestedRouter/index.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tecode/next_react/c9df05307145854e4a934af0e454674e72e0595d/pages/nestedRouter/index.less -------------------------------------------------------------------------------- /pages/nestedRouter/link1/index.js: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | 3 | export default () => ( 4 | 5 | 6 | 7 | 嵌套路由1 8 | 9 | 嵌套路由1 10 | 11 | ); -------------------------------------------------------------------------------- /pages/nestedRouter/link2/index.js: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | 3 | export default () => ( 4 | 5 | 6 | 7 | 嵌套路由2 8 | 9 | 嵌套路由2 10 | 11 | ); -------------------------------------------------------------------------------- /pages/netWork.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Head from 'next/head'; 3 | 4 | export default class NetWork extends Component { 5 | componentDidMount() { 6 | console.log(d3); 7 | } 8 | render() { 9 | return ( 10 | 11 | 12 | My Title 13 | 14 | 15 | 16 | ); 17 | } 18 | } -------------------------------------------------------------------------------- /pages/structChart.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import StructChart from '../components/StructChart'; 3 | 4 | export default () => ; -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | // Illustrational 4 | 'postcss-css-variables': {} 5 | } 6 | } -------------------------------------------------------------------------------- /routers/index.js: -------------------------------------------------------------------------------- 1 | const routes = require('next-routes'); 2 | 3 | module.exports = routes() 4 | .add('demo', '/demo/:id', 'demo') 5 | .add('nestedRouter', '/nested_router', 'nestedRouter') 6 | .add('link1', '/nested_router/link1', 'nestedRouter/link1') 7 | .add('link2', '/nested_router/link2', 'nestedRouter/link2') 8 | .add('netWork', '/netWork', 'netWork') 9 | .add('structChart', '/struct_chart', 'structChart') -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const next = require('next'); 3 | const routes = require('./routers'); 4 | const port = parseInt(process.env.PORT, 10) || 6060; 5 | const app = next({ dev: process.env.NODE_ENV !== 'production' }) 6 | const handler = routes.getRequestHandler(app) 7 | const mobxReact = require('mobx-react'); 8 | 9 | mobxReact.useStaticRendering(true) 10 | 11 | app.prepare() 12 | .then(() => { 13 | const server = express() 14 | server.get('*', (req, res) => { 15 | return handler(req, res) 16 | }) 17 | 18 | server.listen(port, (err) => { 19 | if (err) throw err 20 | console.log(`> Ready on http://localhost:${port}`) 21 | }) 22 | }) -------------------------------------------------------------------------------- /static/images/Screenshot from 2019-04-22 11-51-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tecode/next_react/c9df05307145854e4a934af0e454674e72e0595d/static/images/Screenshot from 2019-04-22 11-51-34.png -------------------------------------------------------------------------------- /static/images/Screenshot from 2019-04-22 11-51-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tecode/next_react/c9df05307145854e4a934af0e454674e72e0595d/static/images/Screenshot from 2019-04-22 11-51-48.png -------------------------------------------------------------------------------- /static/images/antd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tecode/next_react/c9df05307145854e4a934af0e454674e72e0595d/static/images/antd.png -------------------------------------------------------------------------------- /static/images/mobx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tecode/next_react/c9df05307145854e4a934af0e454674e72e0595d/static/images/mobx.png -------------------------------------------------------------------------------- /static/images/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tecode/next_react/c9df05307145854e4a934af0e454674e72e0595d/static/images/next.png -------------------------------------------------------------------------------- /static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "name at package.json", 3 | "short_name": "short name of name at package.json", 4 | "icons": [ 5 | { 6 | "src": "manifest/icon/favicon-32x32.png", 7 | "sizes": "32x32", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "/", 12 | "display": "standalone", 13 | "background_color": "#EFEFEF", 14 | "theme_color": "#EFEFEF" 15 | } -------------------------------------------------------------------------------- /static/manifest/icon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tecode/next_react/c9df05307145854e4a934af0e454674e72e0595d/static/manifest/icon/favicon-32x32.png -------------------------------------------------------------------------------- /store/appStore.js: -------------------------------------------------------------------------------- 1 | import {observable, action} from 'mobx'; 2 | 3 | class AppSore { 4 | @observable name = 'Mobx子页面'; 5 | @observable day = '20'; 6 | @observable treeData = { 7 | 'errcode': 0, 8 | 'errmsg': '成功!', 9 | 'data': [ 10 | { 11 | '_id': 23274, 12 | 'name': '认证相关', 13 | 'project_id': 9003, 14 | 'desc': null, 15 | 'uid': 23628, 16 | 'add_time': 1526606843, 17 | 'up_time': 1526606843, 18 | '__v': 0, 19 | 'index': 0, 20 | 'list': [ 21 | { 22 | '_id': 76297, 23 | 'method': 'GET', 24 | 'catid': 23274, 25 | 'title': '检验sessionId是否有效', 26 | 'path': '/login/sessionId/check', 27 | 'project_id': 9003, 28 | 'uid': 23628, 29 | 'add_time': 1526606926, 30 | 'up_time': 1526607006, 31 | 'index': 0, 32 | 'status': 'done', 33 | 'edit_uid': 0 34 | } 35 | ] 36 | }, 37 | { 38 | '_id': 25164, 39 | 'name': '登录相关', 40 | 'project_id': 9003, 41 | 'desc': null, 42 | 'uid': 23628, 43 | 'add_time': 1527173941, 44 | 'up_time': 1527173941, 45 | '__v': 0, 46 | 'index': 0, 47 | 'list': [ 48 | { 49 | '_id': 84667, 50 | 'method': 'GET', 51 | 'catid': 25164, 52 | 'title': '检测是否绑定', 53 | 'path': '/login/vbind', 54 | 'project_id': 9003, 55 | 'uid': 23628, 56 | 'add_time': 1527173974, 57 | 'up_time': 1527174094, 58 | 'index': 0, 59 | 'status': 'done', 60 | 'edit_uid': 0 61 | }, 62 | { 63 | '_id': 85873, 64 | 'method': 'POST', 65 | 'catid': 25164, 66 | 'title': '解密用户数据/发送验证码', 67 | 'path': '/login/decode', 68 | 'project_id': 9003, 69 | 'uid': 23628, 70 | 'add_time': 1527257062, 71 | 'up_time': 1527257099, 72 | 'index': 1, 73 | 'status': 'done', 74 | 'edit_uid': 0 75 | }, 76 | { 77 | '_id': 85882, 78 | 'method': 'GET', 79 | 'catid': 25164, 80 | 'title': '登录/验证验证码', 81 | 'path': '/login/verifyVcode', 82 | 'project_id': 9003, 83 | 'uid': 23628, 84 | 'add_time': 1527257167, 85 | 'up_time': 1527257245, 86 | 'index': 2, 87 | 'status': 'done', 88 | 'edit_uid': 0 89 | } 90 | ] 91 | }, 92 | { 93 | '_id': 26088, 94 | 'name': '应聘相关', 95 | 'project_id': 9003, 96 | 'desc': null, 97 | 'uid': 23628, 98 | 'add_time': 1527565410, 99 | 'up_time': 1527565410, 100 | '__v': 0, 101 | 'index': 0, 102 | 'list': [ 103 | { 104 | '_id': 88429, 105 | 'method': 'PUT', 106 | 'catid': 26088, 107 | 'title': '应聘人取消应聘', 108 | 'path': '/application/{applyId}/cancel', 109 | 'project_id': 9003, 110 | 'uid': 23628, 111 | 'add_time': 1527566753, 112 | 'up_time': 1527566862, 113 | 'index': 0, 114 | 'status': 'done', 115 | 'edit_uid': 0 116 | }, 117 | { 118 | '_id': 88411, 119 | 'method': 'POST', 120 | 'catid': 26088, 121 | 'title': '申请应聘', 122 | 'path': '/application', 123 | 'project_id': 9003, 124 | 'uid': 23628, 125 | 'add_time': 1527565429, 126 | 'up_time': 1527565472, 127 | 'index': 1, 128 | 'status': 'done', 129 | 'edit_uid': 0 130 | }, 131 | { 132 | '_id': 88537, 133 | 'method': 'PUT', 134 | 'catid': 26088, 135 | 'title': '招聘人操作应聘申请', 136 | 'path': '/application/{applyId}/active', 137 | 'project_id': 9003, 138 | 'uid': 23628, 139 | 'add_time': 1527579261, 140 | 'up_time': 1527579311, 141 | 'index': 2, 142 | 'status': 'done', 143 | 'edit_uid': 0 144 | } 145 | ] 146 | }, 147 | { 148 | '_id': 26298, 149 | 'name': '单位信息相关', 150 | 'project_id': 9003, 151 | 'desc': null, 152 | 'uid': 23628, 153 | 'add_time': 1527643184, 154 | 'up_time': 1527643184, 155 | '__v': 0, 156 | 'index': 0, 157 | 'list': [ 158 | { 159 | '_id': 89455, 160 | 'method': 'GET', 161 | 'catid': 26298, 162 | 'title': '个人单位信息', 163 | 'path': '/recruiter/info', 164 | 'project_id': 9003, 165 | 'uid': 23628, 166 | 'add_time': 1527643196, 167 | 'up_time': 1527682490, 168 | 'index': 0, 169 | 'status': 'done', 170 | 'edit_uid': 0 171 | }, 172 | { 173 | '_id': 89464, 174 | 'method': 'POST', 175 | 'catid': 26298, 176 | 'title': '填写单位信息', 177 | 'path': '/recruiter/info', 178 | 'project_id': 9003, 179 | 'uid': 23628, 180 | 'add_time': 1527643331, 181 | 'up_time': 1527643453, 182 | 'index': 0, 183 | 'status': 'done', 184 | 'edit_uid': 0 185 | }, 186 | { 187 | '_id': 89491, 188 | 'method': 'PUT', 189 | 'catid': 26298, 190 | 'title': '修改单位信息', 191 | 'path': '/recruiter/info', 192 | 'project_id': 9003, 193 | 'uid': 23628, 194 | 'add_time': 1527643833, 195 | 'up_time': 1527755770, 196 | 'index': 0, 197 | 'status': 'done', 198 | 'edit_uid': 0 199 | } 200 | ] 201 | }, 202 | { 203 | '_id': 27222, 204 | 'name': '数据提供', 205 | 'project_id': 9003, 206 | 'desc': null, 207 | 'uid': 23628, 208 | 'add_time': 1528043192, 209 | 'up_time': 1528043192, 210 | '__v': 0, 211 | 'index': 0, 212 | 'list': [ 213 | { 214 | '_id': 93640, 215 | 'method': 'GET', 216 | 'catid': 27222, 217 | 'title': '所有学校信息', 218 | 'path': '/data/university', 219 | 'project_id': 9003, 220 | 'uid': 23628, 221 | 'add_time': 1528043209, 222 | 'up_time': 1528043223, 223 | 'index': 0, 224 | 'status': 'done', 225 | 'edit_uid': 0 226 | }, 227 | { 228 | '_id': 93649, 229 | 'method': 'GET', 230 | 'catid': 27222, 231 | 'title': '学校所有学院列表', 232 | 'path': '/data/college', 233 | 'project_id': 9003, 234 | 'uid': 23628, 235 | 'add_time': 1528043245, 236 | 'up_time': 1528043267, 237 | 'index': 0, 238 | 'status': 'done', 239 | 'edit_uid': 0 240 | }, 241 | { 242 | '_id': 93658, 243 | 'method': 'GET', 244 | 'catid': 27222, 245 | 'title': '学院的专业列表', 246 | 'path': '/data/specialty', 247 | 'project_id': 9003, 248 | 'uid': 23628, 249 | 'add_time': 1528043282, 250 | 'up_time': 1528043317, 251 | 'index': 0, 252 | 'status': 'done', 253 | 'edit_uid': 0 254 | }, 255 | { 256 | '_id': 101416, 257 | 'method': 'GET', 258 | 'catid': 27222, 259 | 'title': '每天招聘的应聘申请数量', 260 | 'path': '/data/statistics/applications', 261 | 'project_id': 9003, 262 | 'uid': 23628, 263 | 'add_time': 1528718980, 264 | 'up_time': 1528725386, 265 | 'index': 0, 266 | 'status': 'done', 267 | 'edit_uid': 0 268 | } 269 | ] 270 | }, 271 | { 272 | '_id': 28518, 273 | 'name': '关于-帮助', 274 | 'project_id': 9003, 275 | 'desc': null, 276 | 'uid': 23628, 277 | 'add_time': 1528526367, 278 | 'up_time': 1528526367, 279 | '__v': 0, 280 | 'index': 0, 281 | 'list': [ 282 | { 283 | '_id': 98428, 284 | 'method': 'POST', 285 | 'catid': 28518, 286 | 'title': '反馈意见', 287 | 'path': '/about/feedback', 288 | 'project_id': 9003, 289 | 'uid': 23628, 290 | 'add_time': 1528526380, 291 | 'up_time': 1528547166, 292 | 'index': 0, 293 | 'status': 'done', 294 | 'edit_uid': 0 295 | }, 296 | { 297 | '_id': 98473, 298 | 'method': 'GET', 299 | 'catid': 28518, 300 | 'title': '查看喜欢的个数', 301 | 'path': '/about/like', 302 | 'project_id': 9003, 303 | 'uid': 23628, 304 | 'add_time': 1528556531, 305 | 'up_time': 1528556584, 306 | 'index': 0, 307 | 'status': 'done', 308 | 'edit_uid': 0 309 | }, 310 | { 311 | '_id': 98482, 312 | 'method': 'PUT', 313 | 'catid': 28518, 314 | 'title': '喜欢', 315 | 'path': '/about/like', 316 | 'project_id': 9003, 317 | 'uid': 23628, 318 | 'add_time': 1528556624, 319 | 'up_time': 1528556645, 320 | 'index': 0, 321 | 'status': 'done', 322 | 'edit_uid': 0 323 | } 324 | ] 325 | }, 326 | { 327 | '_id': 28602, 328 | 'name': '收藏', 329 | 'project_id': 9003, 330 | 'desc': null, 331 | 'uid': 23628, 332 | 'add_time': 1528684198, 333 | 'up_time': 1528684198, 334 | '__v': 0, 335 | 'index': 0, 336 | 'list': [ 337 | { 338 | '_id': 98761, 339 | 'method': 'GET', 340 | 'catid': 28602, 341 | 'title': '查看所有收藏', 342 | 'path': '/collections', 343 | 'project_id': 9003, 344 | 'uid': 23628, 345 | 'add_time': 1528684212, 346 | 'up_time': 1528684242, 347 | 'index': 0, 348 | 'status': 'done', 349 | 'edit_uid': 0 350 | }, 351 | { 352 | '_id': 98770, 353 | 'method': 'POST', 354 | 'catid': 28602, 355 | 'title': '收藏招聘广告', 356 | 'path': '/collections', 357 | 'project_id': 9003, 358 | 'uid': 23628, 359 | 'add_time': 1528684267, 360 | 'up_time': 1528684333, 361 | 'index': 0, 362 | 'status': 'done', 363 | 'edit_uid': 0 364 | }, 365 | { 366 | '_id': 98779, 367 | 'method': 'DELETE', 368 | 'catid': 28602, 369 | 'title': '取消收藏', 370 | 'path': '/collections', 371 | 'project_id': 9003, 372 | 'uid': 23628, 373 | 'add_time': 1528684349, 374 | 'up_time': 1528684370, 375 | 'index': 0, 376 | 'status': 'done', 377 | 'edit_uid': 0 378 | } 379 | ] 380 | }, 381 | { 382 | '_id': 29400, 383 | 'name': '评论相关', 384 | 'project_id': 9003, 385 | 'desc': null, 386 | 'uid': 23628, 387 | 'add_time': 1528859454, 388 | 'up_time': 1528859454, 389 | '__v': 0, 390 | 'index': 0, 391 | 'list': [ 392 | { 393 | '_id': 102775, 394 | 'method': 'DELETE', 395 | 'catid': 29400, 396 | 'title': '删除自己评论', 397 | 'path': '/comments', 398 | 'project_id': 9003, 399 | 'uid': 23628, 400 | 'add_time': 1528859751, 401 | 'up_time': 1528859967, 402 | 'index': 0, 403 | 'status': 'done', 404 | 'edit_uid': 0 405 | }, 406 | { 407 | '_id': 102784, 408 | 'method': 'POST', 409 | 'catid': 29400, 410 | 'title': '发表评论', 411 | 'path': '/comments', 412 | 'project_id': 9003, 413 | 'uid': 23628, 414 | 'add_time': 1528859990, 415 | 'up_time': 1528860043, 416 | 'index': 0, 417 | 'status': 'done', 418 | 'edit_uid': 0 419 | } 420 | ] 421 | }, 422 | { 423 | '_id': 29891, 424 | 'name': '消息相关', 425 | 'project_id': 9003, 426 | 'desc': null, 427 | 'uid': 23628, 428 | 'add_time': 1529236498, 429 | 'up_time': 1529236498, 430 | '__v': 0, 431 | 'index': 0, 432 | 'list': [ 433 | { 434 | '_id': 104365, 435 | 'method': 'DELETE', 436 | 'catid': 29891, 437 | 'title': '删除消息', 438 | 'path': '/message', 439 | 'project_id': 9003, 440 | 'uid': 23628, 441 | 'add_time': 1529236511, 442 | 'up_time': 1529236538, 443 | 'index': 0, 444 | 'status': 'done', 445 | 'edit_uid': 0 446 | } 447 | ] 448 | }, 449 | { 450 | '_id': 23298, 451 | 'name': '用户信息相关', 452 | 'project_id': 9003, 453 | 'desc': null, 454 | 'uid': 23628, 455 | 'add_time': 1526608724, 456 | 'up_time': 1526608740, 457 | '__v': 0, 458 | 'index': 1, 459 | 'list': [ 460 | { 461 | '_id': 76351, 462 | 'method': 'GET', 463 | 'catid': 23298, 464 | 'title': '查看用户个人信息', 465 | 'path': '/users/profile', 466 | 'project_id': 9003, 467 | 'uid': 23628, 468 | 'add_time': 1526608759, 469 | 'up_time': 1526706105, 470 | 'index': 0, 471 | 'status': 'done', 472 | 'edit_uid': 0 473 | }, 474 | { 475 | '_id': 94090, 476 | 'method': 'PUT', 477 | 'catid': 23298, 478 | 'title': '用户更新基本信息', 479 | 'path': '/users/profile', 480 | 'project_id': 9003, 481 | 'uid': 23628, 482 | 'add_time': 1528119757, 483 | 'up_time': 1528120178, 484 | 'index': 0, 485 | 'status': 'done', 486 | 'edit_uid': 0 487 | }, 488 | { 489 | '_id': 76801, 490 | 'method': 'GET', 491 | 'catid': 23298, 492 | 'title': '查看某个用户部分信息', 493 | 'path': '/users/{userId}/profile', 494 | 'project_id': 9003, 495 | 'uid': 23628, 496 | 'add_time': 1526706275, 497 | 'up_time': 1526706301, 498 | 'index': 1, 499 | 'status': 'done', 500 | 'edit_uid': 0 501 | }, 502 | { 503 | '_id': 76963, 504 | 'method': 'GET', 505 | 'catid': 23298, 506 | 'title': '个人应聘记录', 507 | 'path': '/users/application', 508 | 'project_id': 9003, 509 | 'uid': 23628, 510 | 'add_time': 1526797684, 511 | 'up_time': 1528249749, 512 | 'index': 2, 513 | 'status': 'done', 514 | 'edit_uid': 0 515 | }, 516 | { 517 | '_id': 76972, 518 | 'method': 'GET', 519 | 'catid': 23298, 520 | 'title': '个人招聘记录', 521 | 'path': '/users/recruitment', 522 | 'project_id': 9003, 523 | 'uid': 23628, 524 | 'add_time': 1526797883, 525 | 'up_time': 1526798000, 526 | 'index': 3, 527 | 'status': 'done', 528 | 'edit_uid': 0 529 | }, 530 | { 531 | '_id': 92767, 532 | 'method': 'GET', 533 | 'catid': 23298, 534 | 'title': '个人招聘的应聘申请', 535 | 'path': '/users/recruitment/application', 536 | 'project_id': 9003, 537 | 'uid': 23628, 538 | 'add_time': 1527816525, 539 | 'up_time': 1528172774, 540 | 'index': 4, 541 | 'status': 'done', 542 | 'edit_uid': 0 543 | } 544 | ] 545 | }, 546 | { 547 | '_id': 23280, 548 | 'name': '权限相关', 549 | 'project_id': 9003, 550 | 'desc': null, 551 | 'uid': 23628, 552 | 'add_time': 1526606850, 553 | 'up_time': 1526606850, 554 | '__v': 0, 555 | 'index': 2, 556 | 'list': [ 557 | { 558 | '_id': 76315, 559 | 'method': 'POST', 560 | 'catid': 23280, 561 | 'title': '查询用户访问URL权限', 562 | 'path': '/users/permission', 563 | 'project_id': 9003, 564 | 'uid': 23628, 565 | 'add_time': 1526607251, 566 | 'up_time': 1526607925, 567 | 'index': 0, 568 | 'status': 'done', 569 | 'edit_uid': 0 570 | } 571 | ] 572 | }, 573 | { 574 | '_id': 23472, 575 | 'name': '简历信息', 576 | 'project_id': 9003, 577 | 'desc': null, 578 | 'uid': 23628, 579 | 'add_time': 1526782243, 580 | 'up_time': 1526782243, 581 | '__v': 0, 582 | 'index': 3, 583 | 'list': [ 584 | { 585 | '_id': 76855, 586 | 'method': 'GET', 587 | 'catid': 23472, 588 | 'title': '查询个人简历信息', 589 | 'path': '/applicant/info', 590 | 'project_id': 9003, 591 | 'uid': 23628, 592 | 'add_time': 1526782263, 593 | 'up_time': 1528121742, 594 | 'index': 0, 595 | 'status': 'done', 596 | 'edit_uid': 0 597 | }, 598 | { 599 | '_id': 76864, 600 | 'method': 'POST', 601 | 'catid': 23472, 602 | 'title': '填写个人简历信息', 603 | 'path': '/applicant/info/write', 604 | 'project_id': 9003, 605 | 'uid': 23628, 606 | 'add_time': 1526783346, 607 | 'up_time': 1528121940, 608 | 'index': 1, 609 | 'status': 'done', 610 | 'edit_uid': 0 611 | }, 612 | { 613 | '_id': 76873, 614 | 'method': 'PUT', 615 | 'catid': 23472, 616 | 'title': '修改个人简历信息', 617 | 'path': '/applicant/info', 618 | 'project_id': 9003, 619 | 'uid': 23628, 620 | 'add_time': 1526784917, 621 | 'up_time': 1528171719, 622 | 'index': 2, 623 | 'status': 'done', 624 | 'edit_uid': 0 625 | } 626 | ] 627 | }, 628 | { 629 | '_id': 23496, 630 | 'name': 'API管理', 631 | 'project_id': 9003, 632 | 'desc': '后台相关', 633 | 'uid': 23628, 634 | 'add_time': 1526794389, 635 | 'up_time': 1526794389, 636 | '__v': 0, 637 | 'index': 4, 638 | 'list': [ 639 | { 640 | '_id': 76936, 641 | 'method': 'GET', 642 | 'catid': 23496, 643 | 'title': '查询所有API信息', 644 | 'path': '/admin/resources', 645 | 'project_id': 9003, 646 | 'uid': 23628, 647 | 'add_time': 1526794733, 648 | 'up_time': 1526794743, 649 | 'index': 0, 650 | 'status': 'done', 651 | 'edit_uid': 0 652 | }, 653 | { 654 | '_id': 76927, 655 | 'method': 'POST', 656 | 'catid': 23496, 657 | 'title': '注册一个API', 658 | 'path': '/admin/resources', 659 | 'project_id': 9003, 660 | 'uid': 23628, 661 | 'add_time': 1526794625, 662 | 'up_time': 1526794684, 663 | 'index': 1, 664 | 'status': 'done', 665 | 'edit_uid': 0 666 | }, 667 | { 668 | '_id': 76918, 669 | 'method': 'PUT', 670 | 'catid': 23496, 671 | 'title': '更新一个API', 672 | 'path': '/admin/resources/{resId}', 673 | 'project_id': 9003, 674 | 'uid': 23628, 675 | 'add_time': 1526794503, 676 | 'up_time': 1526794819, 677 | 'index': 2, 678 | 'status': 'done', 679 | 'edit_uid': 0 680 | }, 681 | { 682 | '_id': 76909, 683 | 'method': 'DELETE', 684 | 'catid': 23496, 685 | 'title': '删除一个API', 686 | 'path': '/admin/resources/{resId}', 687 | 'project_id': 9003, 688 | 'uid': 23628, 689 | 'add_time': 1526794426, 690 | 'up_time': 1526794516, 691 | 'index': 3, 692 | 'status': 'done', 693 | 'edit_uid': 0 694 | } 695 | ] 696 | }, 697 | { 698 | '_id': 23418, 699 | 'name': '招聘信息相关', 700 | 'project_id': 9003, 701 | 'desc': null, 702 | 'uid': 23628, 703 | 'add_time': 1526635915, 704 | 'up_time': 1526635915, 705 | '__v': 0, 706 | 'index': 5, 707 | 'list': [ 708 | { 709 | '_id': 76684, 710 | 'method': 'POST', 711 | 'catid': 23418, 712 | 'title': '发布招聘信息', 713 | 'path': '/recruitment/publish', 714 | 'project_id': 9003, 715 | 'uid': 23628, 716 | 'add_time': 1526638254, 717 | 'up_time': 1528105599, 718 | 'index': 0, 719 | 'status': 'done', 720 | 'edit_uid': 0 721 | }, 722 | { 723 | '_id': 76648, 724 | 'method': 'GET', 725 | 'catid': 23418, 726 | 'title': '主页展示有效招聘信息', 727 | 'path': '/recruitment', 728 | 'project_id': 9003, 729 | 'uid': 23628, 730 | 'add_time': 1526635945, 731 | 'up_time': 1527146883, 732 | 'index': 1, 733 | 'status': 'done', 734 | 'edit_uid': 0 735 | }, 736 | { 737 | '_id': 76657, 738 | 'method': 'GET', 739 | 'catid': 23418, 740 | 'title': '查询具体招聘信息内容', 741 | 'path': '/detail', 742 | 'project_id': 9003, 743 | 'uid': 23628, 744 | 'add_time': 1526636539, 745 | 'up_time': 1528859554, 746 | 'index': 2, 747 | 'status': 'done', 748 | 'edit_uid': 0 749 | } 750 | ] 751 | }, 752 | { 753 | '_id': 25104, 754 | 'name': '搜索相关', 755 | 'project_id': 9003, 756 | 'desc': null, 757 | 'uid': 23628, 758 | 'add_time': 1527146007, 759 | 'up_time': 1527146007, 760 | '__v': 0, 761 | 'index': 6, 762 | 'list': [ 763 | { 764 | '_id': 84460, 765 | 'method': 'GET', 766 | 'catid': 25104, 767 | 'title': '根据关键字搜索', 768 | 'path': '/search/keyword', 769 | 'project_id': 9003, 770 | 'uid': 23628, 771 | 'add_time': 1527146049, 772 | 'up_time': 1527146660, 773 | 'index': 0, 774 | 'status': 'done', 775 | 'edit_uid': 0 776 | }, 777 | { 778 | '_id': 88699, 779 | 'method': 'GET', 780 | 'catid': 25104, 781 | 'title': '根据薪水进行筛选', 782 | 'path': '/search/salary', 783 | 'project_id': 9003, 784 | 'uid': 23628, 785 | 'add_time': 1527597314, 786 | 'up_time': 1527597373, 787 | 'index': 0, 788 | 'status': 'done', 789 | 'edit_uid': 0 790 | } 791 | ] 792 | } 793 | ] 794 | }; 795 | @action.bound log() { 796 | console.log('mobx'); 797 | } 798 | } 799 | 800 | export default new AppSore(); -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | import appStore from './appStore'; 2 | 3 | export const initializeStore = () => ( 4 | { 5 | homeStore: { name: 'Mobx', age: '12' }, 6 | appStore 7 | } 8 | ); --------------------------------------------------------------------------------