This commit is contained in:
zuiidea
2016-10-14 00:02:33 +08:00
parent 019074d42c
commit 0119dfdc2a
21 changed files with 307 additions and 143 deletions
+2 -1
View File
@@ -5,6 +5,7 @@
},
"dependencies": {
"antd": "^2.0.1",
"classnames": "^2.2.5",
"dva": "1.0.0",
"qs": "^6.2.0",
"react": "^15.1.0",
@@ -35,4 +36,4 @@
"lint": "eslint --fix --ext .js,.jsx .",
"build": "atool-build"
}
}
}
+22 -27
View File
@@ -1,41 +1,36 @@
import React, { PropTypes } from 'react';
import { Menu, Icon } from 'antd';
import { Link } from 'dva/router';
import React, { PropTypes } from 'react'
import { Menu, Icon } from 'antd'
import { Link } from 'dva/router'
import styles from './main.less'
const SubMenu = Menu.SubMenu
function getMenuKeyFromUrl(pathname) {
let key = '';
let key = ''
try {
key = pathname.match(/\/([^\/]*)/i)[1];
key = pathname.match(/\/([^\/]*)/i)[1]
/* eslint no-empty:0 */
} catch (e) {}
return key;
return key
}
function Header({ location }) {
console.log(getMenuKeyFromUrl(location.pathname),location.pathname);
return (
<Menu
selectedKeys={[getMenuKeyFromUrl(location.pathname)]}
mode="horizontal"
theme="dark"
>
<Menu.Item key="users">
<Link to="/users"><Icon type="bars" />Users</Link>
</Menu.Item>
<Menu.Item key="home">
<Link to="/"><Icon type="home" />Home</Link>
</Menu.Item>
<Menu.Item key="404">
<Link to="/page-you-dont-know"><Icon type="frown-circle" />404</Link>
</Menu.Item>
<Menu.Item key="antd">
<a href="https://github.com/dvajs/dva" target="_blank">dva</a>
</Menu.Item>
</Menu>
);
<div className={styles.header}>
<Menu className="header-menu" mode="horizontal">
<SubMenu title={<span><Icon type="user" />吴彦祖</span>}>
<Menu.Item key="signOut">
<a>注销</a>
</Menu.Item>
</SubMenu>
</Menu>
</div>
)
}
Header.propTypes = {
location: PropTypes.object,
};
}
export default Header;
export default Header
-23
View File
@@ -1,23 +0,0 @@
import React, { PropTypes } from 'react';
import styles from './MainLayout.less';
import Header from './Header';
function MainLayout({ children, location }) {
return (
<div className={styles.normal}>
<Header location={location} />
<div className={styles.content}>
<div className={styles.main}>
{children}
</div>
</div>
</div>
);
}
MainLayout.propTypes = {
children: PropTypes.element.isRequired,
location: PropTypes.object,
};
export default MainLayout;
-16
View File
@@ -1,16 +0,0 @@
.normal {
display: flex;
flex-direction: column;
height: 100%;
}
.content {
flex: 1;
display: flex;
}
.main {
padding: 0 8px;
flex: 1 0 auto;
}
+26
View File
@@ -0,0 +1,26 @@
import React, {PropTypes} from 'react'
import {Breadcrumb, Icon} from 'antd'
import styles from './main.less'
function Bread({location}) {
return (
<div className={styles.bread}>
<Breadcrumb>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>
<a href="">Application Center</a>
</Breadcrumb.Item>
<Breadcrumb.Item>
<a href="">Application List</a>
</Breadcrumb.Item>
<Breadcrumb.Item>An Application</Breadcrumb.Item>
</Breadcrumb>
</div>
)
}
Bread.propTypes = {
location: PropTypes.object
}
export default Bread
+34
View File
@@ -0,0 +1,34 @@
body {
height: 100%;
overflow-y: hidden;
background-color: #f8f8f8;
}
// scrollbar
::-webkit-scrollbar-corner {
background-color: transparent;
}
::-webkit-scrollbar-button {
width: 0;
height: 0;
display: none;
}
::-webkit-scrollbar-thumb {
width: 7px;
background-color: #b4babf;
border-radius: 7px;
}
::-webkit-scrollbar {
width: 7px;
height: 7px;
}
::-webkit-scrollbar-track {
width: 15px;
}
::-webkit-scrollbar:hover {
background-color: transparent;
}
+16
View File
@@ -0,0 +1,16 @@
import React, {PropTypes} from 'react'
import styles from './main.less'
function Footer({location}) {
return (
<div className={styles.footer}>
底部
</div>
)
}
Footer.propTypes = {
location: PropTypes.object
}
export default Footer
+35
View File
@@ -0,0 +1,35 @@
import React, { PropTypes } from 'react'
import styles from './main.less'
import classnames from 'classnames'
import Header from './header'
import Bread from './bread'
import Footer from './footer'
import Sider from './sider'
import './common.less'
function Main({ children, location }) {
return (
<div className={styles.layout}>
<aside className={styles.sider}>
<Sider />
</aside>
<div className={styles.main}>
<Header location={location} />
<Bread location={location} />
<div className={styles.container}>
<div className={styles.content}>
{ children }
</div>
</div>
<Footer />
</div>
</div>
)
}
Main.propTypes = {
children: PropTypes.element.isRequired,
location: PropTypes.object,
}
export default Main
+77
View File
@@ -0,0 +1,77 @@
.layout {
position: relative;
height: 100vh;
.sider {
width: 224px;
background: #404040;
position: absolute;
overflow: visible;
padding-bottom: 24px;
height: 100vh;
transition: all 0.3s ease;
.logo {
text-align: center;
height: 40px;
line-height: 40px;
cursor: pointer;
margin: 16px 0;
img {
width: 40px;
margin-right: 8px;
}
span {
vertical-align: text-bottom;
font-size: 16px;
text-transform: uppercase;
display: inline-block;
}
}
}
.header {
:global(.ant-menu-horizontal) {
border: none;
}
box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
}
.bread {
height: 48px;
line-height: 48px;
padding: 0 16px;
margin-bottom: -24px;
}
.main {
margin-left: 224px;
transition: all 0.3s ease;
overflow: auto;
height: 100vh;
.container {
margin: 24px 16px;
.content {
background: #fff;
padding: 24px;
min-height: e("calc(100vh - 168px)");
position: relative;
}
}
}
.footer {
height: 48px;
line-height: 48px;
text-align: center;
font-size: 12px;
color: #999;
background: #fff;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
width: 100%;
}
}
+49
View File
@@ -0,0 +1,49 @@
import React, { PropTypes } from 'react'
import { Menu, Icon } from 'antd'
import styles from './main.less'
const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup;
function Sider({ location }) {
return (
<div>
<div className={styles.logo}>
<img src="https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg" />
<span>Ant Design</span>
</div>
<Menu mode="inline" theme="dark" defaultSelectedKeys={['dashboard']}>
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>Navigation One</span></span>}>
<MenuItemGroup title="Item 1">
<Menu.Item key="1">Option 1</Menu.Item>
<Menu.Item key="2">Option 2</Menu.Item>
</MenuItemGroup>
<MenuItemGroup title="Item 2">
<Menu.Item key="3">Option 3</Menu.Item>
<Menu.Item key="4">Option 4</Menu.Item>
</MenuItemGroup>
</SubMenu>
<SubMenu key="sub2" title={<span><Icon type="appstore" /><span>Navigation Two</span></span>}>
<Menu.Item key="5">Option 5</Menu.Item>
<Menu.Item key="6">Option 6</Menu.Item>
<SubMenu key="sub3" title="Submenu">
<Menu.Item key="7">Option 7</Menu.Item>
<Menu.Item key="8">Option 8</Menu.Item>
</SubMenu>
</SubMenu>
<SubMenu key="sub4" title={<span><Icon type="setting" /><span>Navigation Three</span></span>}>
<Menu.Item key="9">Option 9</Menu.Item>
<Menu.Item key="10">Option 10</Menu.Item>
<Menu.Item key="11">Option 11</Menu.Item>
<Menu.Item key="12">Option 12</Menu.Item>
</SubMenu>
</Menu>
</div>
)
}
Sider.propTypes = {
location: PropTypes.object,
}
export default Sider
@@ -1,6 +1,6 @@
import React, {PropTypes} from 'react'
import {Form, Input, Button, Select} from 'antd'
import styles from './UserSearch.less'
import styles from './search.less'
const UserSearch = ({
field,
+7 -7
View File
@@ -1,15 +1,15 @@
import './index.html';
import './index.less';
import dva from 'dva';
import './index.html'
import './index.less'
import dva from 'dva'
// 1. Initialize
const app = dva();
const app = dva()
// 2. Model
app.model(require('./models/users'));
app.model(require('./models/users'))
// 3. Router
app.router(require('./router'));
app.router(require('./router'))
// 4. Start
app.start('#root');
app.start('#root')
+3 -3
View File
@@ -1,13 +1,13 @@
import React from 'react'
import { Router, Route } from 'dva/router'
import HomePage from './routes/HomePage'
import Index from './routes/index'
import NotFound from './routes/NotFound'
import Users from './routes/Users'
import Users from './routes/users'
export default function ({ history }) {
return (
<Router history={history}>
<Route path="/" component={HomePage} />
<Route path="/" component={Index} />
<Route path="/users" component={Users} />
<Route path="*" component={NotFound} />
</Router>
-22
View File
@@ -1,22 +0,0 @@
import React, { Component, PropTypes } from 'react';
import { connect } from 'dva';
import { Link } from 'dva/router';
import styles from './IndexPage.less';
function IndexPage() {
return (
<div className={styles.normal}>
<h1>Welcome to dva!</h1>
<hr />
<ul className={styles.list}>
<li>To get started, edit <code>src/index.js</code> and save to reload.</li>
<li><a href="https://github.com/sorrycc/blog/issues/8" target="_blank">Getting Started</a></li>
</ul>
</div>
);
}
IndexPage.propTypes = {
};
export default connect()(IndexPage);
-8
View File
@@ -1,8 +0,0 @@
.normal {
margin: 100px;
}
.list {
margin-top: 20px;
}
+29 -29
View File
@@ -1,19 +1,19 @@
import React, { PropTypes } from 'react';
import { routerRedux } from 'dva/router';
import { connect } from 'dva';
import MainLayout from '../components/Layout/MainLayout';
import styles from './Users.less';
import UserList from '../components/Users/UserList';
import UserSearch from '../components/Users/UserSearch';
import UserModal from '../components/Users/UserModal';
import React, { PropTypes } from 'react'
import { routerRedux } from 'dva/router'
import { connect } from 'dva'
import Main from '../components/layout/main'
import styles from './users.less'
import UserList from '../components/users/list'
import UserSearch from '../components/users/search'
import UserModal from '../components/users/modal'
function Users({ location, dispatch, users }) {
const {
loading, list, total, current,
currentItem, modalVisible, modalType,
} = users;
} = users
const { field, keyword } = location.query;
const { field, keyword } = location.query
const userModalProps = {
item: modalType === 'create' ? {} : currentItem,
@@ -23,14 +23,14 @@ function Users({ location, dispatch, users }) {
dispatch({
type: `users/${modalType}`,
payload: data,
});
})
},
onCancel() {
dispatch({
type: 'users/hideModal',
});
})
},
};
}
const userListProps = {
dataSource: list,
@@ -41,13 +41,13 @@ function Users({ location, dispatch, users }) {
dispatch(routerRedux.push({
pathname: '/users',
query: { page },
}));
}))
},
onDeleteItem(id) {
dispatch({
type: 'users/delete',
payload: id,
});
})
},
onEditItem(item) {
dispatch({
@@ -56,9 +56,9 @@ function Users({ location, dispatch, users }) {
modalType: 'update',
currentItem: item,
},
});
})
},
};
}
const userSearchProps = {
field,
@@ -67,7 +67,7 @@ function Users({ location, dispatch, users }) {
dispatch({
type: 'users/query',
payload: fieldsValue,
});
})
},
onAdd() {
dispatch({
@@ -75,35 +75,35 @@ function Users({ location, dispatch, users }) {
payload: {
modalType: 'create',
},
});
})
},
};
}
// 解决 Form.create initialValue 的问题
// 每次创建一个全新的组件, 而不做diff
// 如果你使用了redux, 请移步 http://react-component.github.io/form/examples/redux.html
const UserModalGen = () =>
<UserModal {...userModalProps} />;
<UserModal {...userModalProps} />
return (
<MainLayout location={location}>
<Main location={location}>
<div className={styles.normal}>
<UserSearch {...userSearchProps} />
<UserList {...userListProps} />
<UserModalGen />
</div>
</MainLayout>
);
</Main>
)
}
Users.propTypes = {
users: PropTypes.object,
location: PropTypes.object,
dispatch: PropTypes.func,
};
function mapStateToProps({ users }) {
return { users };
}
export default connect(mapStateToProps)(Users);
function mapStateToProps({ users }) {
return { users }
}
export default connect(mapStateToProps)(Users)
@@ -1,6 +1,6 @@
import React from 'react';
import { Link } from 'dva/router';
import styles from './HomePage.less';
import React from 'react'
import { Link } from 'dva/router'
import styles from './Index.less'
function HomePage() {
return (
@@ -11,10 +11,10 @@ function HomePage() {
<li>You can go to <Link to="/users">/users</Link></li>
</ul>
</div>
);
)
}
HomePage.propTypes = {
};
}
export default HomePage;
export default HomePage