Modal 对话框

用作显示系统的重要信息,并请求用户进行操作反馈,eg:删除某个重要内容时,弹出 Modal 进行二次确认。

规则

  • 尽可能少用。Modal 会打断用户操作,只用在重要的时候。

  • 标题应该简明,不能超过 1 行;描述内容应该简明、完整,一般不多于 2 行。

  • 操作按钮最多到 3 个(竖排),一般为 1-2 个(横排);3 个以上建议使用组件 ActionSheet 来完成。

  • 一般将用户最可能点击的按钮,放在右侧。另外,取消按钮应当始终放在左侧。

代码演示

基本

基本对话框。

  1. import { Modal, List, Button, WhiteSpace, WingBlank, Icon } from 'antd-mobile';
  2. function closest(el, selector) {
  3. const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
  4. while (el) {
  5. if (matchesSelector.call(el, selector)) {
  6. return el;
  7. }
  8. el = el.parentElement;
  9. }
  10. return null;
  11. }
  12. class App extends React.Component {
  13. constructor(props) {
  14. super(props);
  15. this.state = {
  16. modal1: false,
  17. modal2: false,
  18. };
  19. }
  20. showModal = key => (e) => {
  21. e.preventDefault(); // 修复 Android 上点击穿透
  22. this.setState({
  23. [key]: true,
  24. });
  25. }
  26. onClose = key => () => {
  27. this.setState({
  28. [key]: false,
  29. });
  30. }
  31. onWrapTouchStart = (e) => {
  32. // fix touch to scroll background page on iOS
  33. if (!/iPhone|iPod|iPad/i.test(navigator.userAgent)) {
  34. return;
  35. }
  36. const pNode = closest(e.target, '.am-modal-content');
  37. if (!pNode) {
  38. e.preventDefault();
  39. }
  40. }
  41. render() {
  42. return (
  43. <WingBlank>
  44. <Button onClick={this.showModal('modal1')}><Icon type="up" />basic<Icon type="up" /></Button>
  45. <WhiteSpace />
  46. <Modal
  47. visible={this.state.modal1}
  48. transparent
  49. maskClosable={false}
  50. onClose={this.onClose('modal1')}
  51. title="Title"
  52. footer={[{ text: 'Ok', onPress: () => { console.log('ok'); this.onClose('modal1')(); } }]}
  53. wrapProps={{ onTouchStart: this.onWrapTouchStart }}
  54. afterClose={() => { alert('afterClose'); }}
  55. >
  56. <div style={{ height: 100, overflow: 'scroll' }}>
  57. scoll content...<br />
  58. scoll content...<br />
  59. scoll content...<br />
  60. scoll content...<br />
  61. scoll content...<br />
  62. scoll content...<br />
  63. </div>
  64. </Modal>
  65. <Button onClick={this.showModal('modal2')}>popup</Button>
  66. <WhiteSpace />
  67. <Modal
  68. popup
  69. visible={this.state.modal2}
  70. onClose={this.onClose('modal2')}
  71. animationType="slide-up"
  72. afterClose={() => { alert('afterClose'); }}
  73. >
  74. <List renderHeader={() => <div>委托买入</div>} className="popup-list">
  75. {['股票名称', '股票代码', '买入价格'].map((i, index) => (
  76. <List.Item key={index}>{i}</List.Item>
  77. ))}
  78. <List.Item>
  79. <Button type="primary" onClick={this.onClose('modal2')}>买入</Button>
  80. </List.Item>
  81. </List>
  82. </Modal>
  83. </WingBlank>
  84. );
  85. }
  86. }
  87. ReactDOM.render(<App />, mountNode);
  1. .popup-list .am-list-body {
  2. height: 210px;
  3. overflow: auto;
  4. }

警告弹窗

包含无按钮, 确认框, 多按钮情况。

  1. import { Modal, Button, WhiteSpace, WingBlank, Toast } from 'antd-mobile';
  2. const alert = Modal.alert;
  3. const showAlert = () => {
  4. const alertInstance = alert('Delete', 'Are you sure???', [
  5. { text: 'Cancel', onPress: () => console.log('cancel'), style: 'default' },
  6. { text: 'OK', onPress: () => console.log('ok') },
  7. ]);
  8. setTimeout(() => {
  9. // 可以调用close方法以在外部close
  10. console.log('auto close');
  11. alertInstance.close();
  12. }, 500000);
  13. };
  14. const App = () => (
  15. <WingBlank size="lg">
  16. <WhiteSpace size="lg" />
  17. <Button onClick={showAlert}>customized buttons</Button>
  18. <WhiteSpace size="lg" />
  19. <Button
  20. onClick={() =>
  21. alert('Delete', 'Are you sure???', [
  22. { text: 'Cancel', onPress: () => console.log('cancel') },
  23. { text: 'Ok', onPress: () => console.log('ok') },
  24. ])
  25. }
  26. >
  27. confirm
  28. </Button>
  29. <WhiteSpace size="lg" />
  30. <Button
  31. onClick={() =>
  32. alert('Much Buttons', <div>More than two buttons</div>, [
  33. { text: 'Button1', onPress: () => console.log('第0个按钮被点击了') },
  34. { text: 'Button2', onPress: () => console.log('第1个按钮被点击了') },
  35. { text: 'Button3', onPress: () => console.log('第2个按钮被点击了') },
  36. ])
  37. }
  38. >
  39. more than two buttons
  40. </Button>
  41. <WhiteSpace size="lg" />
  42. <Button
  43. onClick={() =>
  44. alert('Delete', 'Are you sure???', [
  45. { text: 'Cancel', onPress: () => console.log('cancel') },
  46. {
  47. text: 'Ok',
  48. onPress: () =>
  49. new Promise((resolve) => {
  50. Toast.info('onPress Promise', 1);
  51. setTimeout(resolve, 1000);
  52. }),
  53. },
  54. ])
  55. }
  56. >
  57. promise
  58. </Button>
  59. <WhiteSpace size="lg" />
  60. </WingBlank>
  61. );
  62. ReactDOM.render(<App />, mountNode);

输入弹窗

包含输入普通文字, 密码, 登录信息样式。

  1. import { Modal, Button, WingBlank, WhiteSpace, Toast } from 'antd-mobile';
  2. const prompt = Modal.prompt;
  3. const App = () => (
  4. <WingBlank size="lg">
  5. <WhiteSpace size="lg" />
  6. <Button onClick={() => prompt('input name', 'please input your name',
  7. [
  8. {
  9. text: 'Close',
  10. onPress: value => new Promise((resolve) => {
  11. Toast.info('onPress promise resolve', 1);
  12. setTimeout(() => {
  13. resolve();
  14. console.log(`value:${value}`);
  15. }, 1000);
  16. }),
  17. },
  18. {
  19. text: 'Hold on',
  20. onPress: value => new Promise((resolve, reject) => {
  21. Toast.info('onPress promise reject', 1);
  22. setTimeout(() => {
  23. reject();
  24. console.log(`value:${value}`);
  25. }, 1000);
  26. }),
  27. },
  28. ], 'default', null, ['input your name'])}
  29. >promise</Button>
  30. <WhiteSpace size="lg" />
  31. <Button onClick={() => prompt('defaultValue', 'defaultValue for prompt', [
  32. { text: 'Cancel' },
  33. { text: 'Submit', onPress: value => console.log(`输入的内容:${value}`) },
  34. ], 'default', '100')}
  35. >defaultValue</Button>
  36. <WhiteSpace size="lg" />
  37. <Button onClick={() => prompt(
  38. 'Password',
  39. 'Password Message',
  40. password => console.log(`password: ${password}`),
  41. 'secure-text',
  42. )}
  43. >secure-text</Button>
  44. <WhiteSpace size="lg" />
  45. <Button onClick={() => prompt(
  46. 'Password',
  47. 'You can custom buttons',
  48. [
  49. { text: '取消' },
  50. { text: '提交', onPress: password => console.log(`密码为:${password}`) },
  51. ],
  52. 'secure-text',
  53. )}
  54. >custom buttons</Button>
  55. <WhiteSpace size="lg" />
  56. <Button onClick={() => prompt(
  57. 'Login',
  58. 'Please input login information',
  59. (login, password) => console.log(`login: ${login}, password: ${password}`),
  60. 'login-password',
  61. null,
  62. ['Please input name', 'Please input password'],
  63. )}
  64. >login-password</Button>
  65. <WhiteSpace size="lg" />
  66. </WingBlank>
  67. );
  68. ReactDOM.render(<App />, mountNode);

操作弹窗

操作对话框。

  1. import { Modal, Button, WhiteSpace, WingBlank } from 'antd-mobile';
  2. const operation = Modal.operation;
  3. const App = () => (
  4. <WingBlank size="lg">
  5. <WhiteSpace size="lg" />
  6. <Button onClick={() => operation([
  7. { text: '标为未读', onPress: () => console.log('标为未读被点击了') },
  8. { text: '置顶聊天', onPress: () => console.log('置顶聊天被点击了') },
  9. ])}
  10. >operation</Button>
  11. <WhiteSpace size="lg" />
  12. </WingBlank>
  13. );
  14. ReactDOM.render(<App />, mountNode);

Modal对话框 - 图1

API

Modal

属性说明类型默认值
afterCloseModal 完全关闭后的回调function
visible对话框是否可见Booleanfalse
closable是否显示关闭按钮Booleanfalse
maskClosable点击蒙层是否允许关闭Booleantrue
onClose点击 x 或 mask 回调(): void
transparent是否背景透明Booleanfalse
popup是否弹窗模式Booleanfalse
animationType可选: 'slide-down / up' / 'fade' / 'slide'Stringfade
title标题React.Element
footer底部内容Array {text, onPress}[]
platform设定组件的平台特有样式, 可选值为 android, ios, 默认为 iosStringios'
transitionNameModal 主内容动画 classNameString
maskTransitionNamemask 动画 classNameString
className手动设置 Modal 的 classNameString
wrapClassName手动设置 Modal wrap 的 classNameString

Modal.alert(title, message, actions?, platform?)

属性说明类型默认值
title标题String 或 React.Element
message提示信息String 或 React.Element
actions按钮组, {text, onPress, style}Array
platform设定组件的平台特有样式, 可选值为 android, ios, 默认为 iosString'ios'

Modal.alert(title, message, actions?, platform?).close() 可以在外部关闭 Alert

Modal.prompt(title, message, callbackOrActions, type?, defaultValue?, placeholders?, platform?)

属性说明类型默认值
title标题String 或 React.Element
message提示信息String 或 React.Element
callbackOrActions按钮组 {text, onPress} 或回调函数Array or Function
typeprompt 的样式String (default, secure-text, login-password)default
defaultValue默认值(input 为 password 类型不支持)String-
placeholders'', ''String[]-
platform设定组件的平台特有样式, 可选值为 android, ios, 默认为 iosString'ios'

Modal.prompt(title, message, callbackOrActions, type?, defaultValue?, placeholders?, platform?).close() 可以在外部关闭 prompt`

Modal.operation(actions?, platform?)

属性说明类型默认值
actions按钮组, {text, onPress, style}Array
platform设定组件的平台特有样式, 可选值为 android, ios, 默认为 iosString'ios'

Modal.operation(actions?, platform?).close() 可以在外部关闭 operation`