Browse Source

chang to new context api

pull/1290/head
jim 8 years ago
committed by 陈帅
parent
commit
0a3865826b
  1. 8
      package.json
  2. 196
      src/components/Login/LoginItem.js
  3. 23
      src/components/Login/LoginTab.js
  4. 62
      src/components/Login/index.js
  5. 4
      src/components/Login/loginContext.js
  6. 10
      src/components/Login/map.js

8
package.json

@ -23,7 +23,9 @@
"dependencies": {
"@antv/data-set": "^0.8.0",
"@babel/polyfill": "^7.0.0-beta.36",
"antd": "^3.3.3",
"@types/react": "^16.3.5",
"@types/react-dom": "^16.0.4",
"antd": "^3.4.0",
"babel-runtime": "^6.9.2",
"bizcharts": "^3.1.3-beta.1",
"bizcharts-plugin-slider": "^2.0.1",
@ -40,10 +42,10 @@
"prop-types": "^15.5.10",
"qs": "^6.5.0",
"rc-drawer-menu": "^0.5.0",
"react": "^16.2.0",
"react": "^16.3.1",
"react-container-query": "^0.9.1",
"react-document-title": "^2.0.3",
"react-dom": "^16.2.0",
"react-dom": "^16.3.1",
"react-fittext": "^1.0.0",
"rollbar": "^2.3.4",
"url-polyfill": "^1.0.10"

196
src/components/Login/LoginItem.js

@ -1,104 +1,124 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Form, Button, Row, Col } from 'antd';
import { Form, Input, Button, Row, Col } from 'antd';
import omit from 'omit.js';
import styles from './index.less';
import map from './map';
import ItemMap from './map';
import LoginContext from './loginContext';
const FormItem = Form.Item;
function generator({ defaultProps, defaultRules, type }) {
return WrappedComponent => {
return class BasicComponent extends Component {
static contextTypes = {
form: PropTypes.object,
updateActive: PropTypes.func,
};
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
componentDidMount() {
if (this.context.updateActive) {
this.context.updateActive(this.props.name);
}
}
componentWillUnmount() {
class WarpFormItem extends Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
componentDidMount() {
if (this.props.updateActive) {
this.props.updateActive(this.props.name);
}
}
componentWillUnmount() {
clearInterval(this.interval);
}
onGetCaptcha = () => {
let count = 59;
this.setState({ count });
if (this.props.onGetCaptcha) {
this.props.onGetCaptcha();
}
this.interval = setInterval(() => {
count -= 1;
this.setState({ count });
if (count === 0) {
clearInterval(this.interval);
}
onGetCaptcha = () => {
let count = 59;
this.setState({ count });
if (this.props.onGetCaptcha) {
this.props.onGetCaptcha();
}
this.interval = setInterval(() => {
count -= 1;
this.setState({ count });
if (count === 0) {
clearInterval(this.interval);
}
}, 1000);
};
render() {
const { getFieldDecorator } = this.context.form;
const options = {};
let otherProps = {};
const { onChange, defaultValue, rules, name, ...restProps } = this.props;
const { count } = this.state;
options.rules = rules || defaultRules;
if (onChange) {
options.onChange = onChange;
}
if (defaultValue) {
options.initialValue = defaultValue;
}
otherProps = restProps || otherProps;
if (type === 'Captcha') {
const inputProps = omit(otherProps, ['onGetCaptcha']);
return (
<FormItem>
<Row gutter={8}>
<Col span={16}>
{getFieldDecorator(name, options)(
<WrappedComponent {...defaultProps} {...inputProps} />
)}
</Col>
<Col span={8}>
<Button
disabled={count}
className={styles.getCaptcha}
size="large"
onClick={this.onGetCaptcha}
>
{count ? `${count} s` : '获取验证码'}
</Button>
</Col>
</Row>
</FormItem>
);
}
return (
<FormItem>
{getFieldDecorator(name, options)(
<WrappedComponent {...defaultProps} {...otherProps} />
)}
</FormItem>
);
}
}, 1000);
};
getFormItemOptions = ({ onChange, defaultValue, rules }) => {
const options = {
rules: rules || this.customprops.rules,
};
if (onChange) {
options.onChange = onChange;
}
if (defaultValue) {
options.initialValue = defaultValue;
}
return options;
};
render() {
const { count } = this.state;
const { getFieldDecorator } = this.props.form;
// 这么写是为了防止restProps中 带入 onChange, defaultValue, rules props
const {
onChange,
customprops,
defaultValue,
rules,
name,
updateActive,
...restProps
} = this.props;
// get getFieldDecorator props
const options = this.getFormItemOptions(this.props);
const otherProps = restProps || {};
if (this.props.type === 'Captcha') {
const inputProps = omit(otherProps, ['onGetCaptcha']);
return (
<FormItem>
<Row gutter={8}>
<Col span={16}>
{getFieldDecorator(name, options)(
<Input {...this.props.customprops} {...inputProps} />
)}
</Col>
<Col span={8}>
<Button
disabled={count}
className={styles.getCaptcha}
size="large"
onClick={this.onGetCaptcha}
>
{count ? `${count} s` : '获取验证码'}
</Button>
</Col>
</Row>
</FormItem>
);
}
return (
<FormItem>
{getFieldDecorator(name, options)(<Input {...this.props.customprops} {...otherProps} />)}
</FormItem>
);
}
}
const LoginItem = {};
Object.keys(map).forEach(item => {
LoginItem[item] = generator({
defaultProps: map[item].props,
defaultRules: map[item].rules,
type: item,
})(map[item].component);
Object.keys(ItemMap).forEach(key => {
const item = ItemMap[key];
LoginItem[key] = props => {
return (
<LoginContext.Consumer>
{context => (
<WarpFormItem
customprops={item.props}
{...props}
rules={item.rules}
type={key}
updateActive={context.updateActive}
form={context.form}
/>
)}
</LoginContext.Consumer>
);
};
});
export default LoginItem;

23
src/components/Login/LoginTab.js

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Tabs } from 'antd';
import LoginContext from './loginContext';
const { TabPane } = Tabs;
@ -12,21 +12,24 @@ const generateId = (() => {
};
})();
export default class LoginTab extends Component {
static __ANT_PRO_LOGIN_TAB = true;
static contextTypes = {
tabUtil: PropTypes.object,
};
class LoginTab extends Component {
constructor(props) {
super(props);
this.uniqueId = generateId('login-tab-');
}
componentWillMount() {
if (this.context.tabUtil) {
this.context.tabUtil.addTab(this.uniqueId);
}
componentDidMount() {
this.props.tabUtil.addTab(this.uniqueId);
}
render() {
return <TabPane {...this.props} />;
}
}
const warpContext = props => {
return (
<LoginContext.Consumer>
{value => <LoginTab tabUtil={value.tabUtil} {...props} />}
</LoginContext.Consumer>
);
};
export default warpContext;

62
src/components/Login/index.js

@ -6,6 +6,7 @@ import LoginItem from './LoginItem';
import LoginTab from './LoginTab';
import LoginSubmit from './LoginSubmit';
import styles from './index.less';
import LoginContext from './loginContext';
@Form.create()
class Login extends Component {
@ -21,17 +22,18 @@ class Login extends Component {
onTabChange: PropTypes.func,
onSubmit: PropTypes.func,
};
static childContextTypes = {
tabUtil: PropTypes.object,
form: PropTypes.object,
updateActive: PropTypes.func,
};
state = {
type: this.props.defaultActiveKey,
tabs: [],
active: {},
};
getChildContext() {
onSwitch = type => {
this.setState({
type,
});
this.props.onTabChange(type);
};
getContext = () => {
return {
tabUtil: {
addTab: id => {
@ -58,12 +60,6 @@ class Login extends Component {
});
},
};
}
onSwitch = type => {
this.setState({
type,
});
this.props.onTabChange(type);
};
handleSubmit = e => {
e.preventDefault();
@ -83,32 +79,34 @@ class Login extends Component {
return;
}
// eslint-disable-next-line
if (item.type.__ANT_PRO_LOGIN_TAB) {
if (item.type.name === 'warpContext') {
TabChildren.push(item);
} else {
otherChildren.push(item);
}
});
return (
<div className={classNames(className, styles.login)}>
<Form onSubmit={this.handleSubmit}>
{tabs.length ? (
<div>
<Tabs
animated={false}
className={styles.tabs}
activeKey={type}
onChange={this.onSwitch}
>
{TabChildren}
</Tabs>
{otherChildren}
</div>
) : (
[...children]
)}
</Form>
</div>
<LoginContext.Provider value={this.getContext()}>
<div className={classNames(className, styles.login)}>
<Form onSubmit={this.handleSubmit}>
{tabs.length ? (
<>
<Tabs
animated={false}
className={styles.tabs}
activeKey={type}
onChange={this.onSwitch}
>
{TabChildren}
</Tabs>
{otherChildren}
</>
) : (
[...children]
)}
</Form>
</div>
</LoginContext.Provider>
);
}
}

4
src/components/Login/loginContext.js

@ -0,0 +1,4 @@
import { createContext } from 'react';
const LoginContext = createContext();
export default LoginContext;

10
src/components/Login/map.js

@ -1,10 +1,9 @@
import React from 'react';
import { Input, Icon } from 'antd';
import { Icon } from 'antd';
import styles from './index.less';
const map = {
export default {
UserName: {
component: Input,
props: {
size: 'large',
prefix: <Icon type="user" className={styles.prefixIcon} />,
@ -18,7 +17,6 @@ const map = {
],
},
Password: {
component: Input,
props: {
size: 'large',
prefix: <Icon type="lock" className={styles.prefixIcon} />,
@ -33,7 +31,6 @@ const map = {
],
},
Mobile: {
component: Input,
props: {
size: 'large',
prefix: <Icon type="mobile" className={styles.prefixIcon} />,
@ -51,7 +48,6 @@ const map = {
],
},
Captcha: {
component: Input,
props: {
size: 'large',
prefix: <Icon type="mail" className={styles.prefixIcon} />,
@ -65,5 +61,3 @@ const map = {
],
},
};
export default map;

Loading…
Cancel
Save