modal.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. // +----------------------------------------------------------------------
  2. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  3. // +----------------------------------------------------------------------
  4. // | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
  5. // +----------------------------------------------------------------------
  6. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  7. // +----------------------------------------------------------------------
  8. // | Author: CRMEB Team <admin@crmeb.com>
  9. // +----------------------------------------------------------------------
  10. import Vue from 'vue';
  11. import Modal from 'iview/src/components/modal/modal.vue';
  12. import Button from 'iview/src/components/button/button.vue';
  13. import Locale from 'iview/src/mixins/locale';
  14. const prefixCls = 'ivu-modal-alert';
  15. Modal.newInstance = (properties) => {
  16. const _props = properties || {};
  17. const Instance = new Vue({
  18. mixins: [Locale],
  19. data: Object.assign({}, _props, {
  20. visible: false,
  21. width: 416,
  22. title: '',
  23. body: '',
  24. iconType: '',
  25. iconName: '',
  26. okText: undefined,
  27. cancelText: undefined,
  28. showCancel: false,
  29. loading: false,
  30. buttonLoading: false,
  31. scrollable: false,
  32. closable: true,
  33. closing: false, // 关闭有动画,期间使用此属性避免重复点击
  34. }),
  35. render(h) {
  36. let footerVNodes = [];
  37. if (this.showCancel) {
  38. footerVNodes.push(
  39. h(
  40. Button,
  41. {
  42. props: {
  43. type: 'text',
  44. size: 'large',
  45. },
  46. on: {
  47. click: this.cancel,
  48. },
  49. },
  50. this.localeCancelText,
  51. ),
  52. );
  53. }
  54. // footerVNodes.push(h(Button, {
  55. // props: {
  56. // type: 'primary',
  57. // size: 'large',
  58. // loading: this.buttonLoading
  59. // },
  60. // on: {
  61. // click: this.ok
  62. // }
  63. // }, this.localeOkText))
  64. // render content
  65. let body_render;
  66. if (this.render) {
  67. body_render = h(
  68. 'div',
  69. {
  70. attrs: {
  71. class: `${prefixCls}-body ${prefixCls}-body-render`,
  72. },
  73. },
  74. [this.render(h)],
  75. );
  76. } else {
  77. body_render = h(
  78. 'div',
  79. {
  80. attrs: {
  81. class: `${prefixCls}-body`,
  82. },
  83. },
  84. [
  85. h('div', {
  86. domProps: {
  87. innerHTML: this.body,
  88. },
  89. }),
  90. ],
  91. );
  92. }
  93. // when render with no title, hide head
  94. let head_render;
  95. if (this.title) {
  96. head_render = h(
  97. 'div',
  98. {
  99. attrs: {
  100. class: `${prefixCls}-head`,
  101. },
  102. slot: 'header',
  103. },
  104. [
  105. h('h2', {
  106. attrs: {
  107. class: `${prefixCls}-head-title`,
  108. },
  109. domProps: {
  110. innerHTML: this.title,
  111. style: 'margin-bottom: 10px;',
  112. },
  113. }),
  114. ],
  115. );
  116. }
  117. return h(
  118. Modal,
  119. {
  120. props: Object.assign({}, _props, {
  121. width: this.width,
  122. scrollable: this.scrollable,
  123. closable: this.closable,
  124. }),
  125. domProps: {
  126. value: this.visible,
  127. },
  128. on: {
  129. input: (status) => {
  130. this.visible = status;
  131. },
  132. 'on-cancel': this.cancel,
  133. },
  134. },
  135. [
  136. h(
  137. 'div',
  138. {
  139. attrs: {
  140. class: prefixCls,
  141. },
  142. },
  143. [
  144. head_render,
  145. body_render,
  146. h(
  147. 'div',
  148. {
  149. attrs: {
  150. class: `${prefixCls}-footer`,
  151. },
  152. },
  153. footerVNodes,
  154. ),
  155. ],
  156. ),
  157. ],
  158. );
  159. },
  160. computed: {
  161. iconTypeCls() {
  162. return [`${prefixCls}-head-icon`, `${prefixCls}-head-icon-${this.iconType}`];
  163. },
  164. iconNameCls() {
  165. return ['ivu-icon', `ivu-icon-${this.iconName}`];
  166. },
  167. localeOkText() {
  168. if (this.okText) {
  169. return this.okText;
  170. } else {
  171. return this.t('i.modal.okText');
  172. }
  173. },
  174. localeCancelText() {
  175. if (this.cancelText) {
  176. return this.cancelText;
  177. } else {
  178. return this.t('i.modal.cancelText');
  179. }
  180. },
  181. },
  182. methods: {
  183. cancel() {
  184. if (this.closing) return;
  185. this.$children[0].visible = false;
  186. this.buttonLoading = false;
  187. this.onCancel();
  188. this.remove();
  189. },
  190. ok() {
  191. if (this.closing) return;
  192. if (this.loading) {
  193. this.buttonLoading = true;
  194. } else {
  195. this.$children[0].visible = false;
  196. this.remove();
  197. }
  198. this.onOk();
  199. },
  200. remove() {
  201. this.closing = true;
  202. setTimeout(() => {
  203. this.closing = false;
  204. this.destroy();
  205. }, 300);
  206. },
  207. destroy() {
  208. this.$destroy();
  209. if (this.$el) {
  210. document.body.removeChild(this.$el);
  211. }
  212. this.onRemove();
  213. },
  214. onOk() {},
  215. onCancel() {},
  216. onRemove() {},
  217. },
  218. });
  219. const component = Instance.$mount();
  220. document.body.appendChild(component.$el);
  221. const modal = Instance.$children[0];
  222. return {
  223. show(props) {
  224. modal.$parent.showCancel = props.showCancel;
  225. modal.$parent.iconType = props.icon;
  226. switch (props.icon) {
  227. case 'info':
  228. modal.$parent.iconName = 'ios-information-circle';
  229. break;
  230. case 'success':
  231. modal.$parent.iconName = 'ios-checkmark-circle';
  232. break;
  233. case 'warning':
  234. modal.$parent.iconName = 'ios-alert';
  235. break;
  236. case 'error':
  237. modal.$parent.iconName = 'ios-close-circle';
  238. break;
  239. case 'confirm':
  240. modal.$parent.iconName = 'ios-help-circle';
  241. break;
  242. }
  243. if ('width' in props) {
  244. modal.$parent.width = props.width;
  245. }
  246. if ('closable' in props) {
  247. modal.$parent.closable = props.closable;
  248. }
  249. if ('title' in props) {
  250. modal.$parent.title = props.title;
  251. }
  252. if ('content' in props) {
  253. modal.$parent.body = props.content;
  254. }
  255. if ('okText' in props) {
  256. modal.$parent.okText = props.okText;
  257. }
  258. if ('cancelText' in props) {
  259. modal.$parent.cancelText = props.cancelText;
  260. }
  261. if ('onCancel' in props) {
  262. modal.$parent.onCancel = props.onCancel;
  263. }
  264. if ('onOk' in props) {
  265. modal.$parent.onOk = props.onOk;
  266. }
  267. // async for ok
  268. if ('loading' in props) {
  269. modal.$parent.loading = props.loading;
  270. }
  271. if ('scrollable' in props) {
  272. modal.$parent.scrollable = props.scrollable;
  273. }
  274. // notice when component destroy
  275. modal.$parent.onRemove = props.onRemove;
  276. modal.visible = true;
  277. },
  278. remove() {
  279. modal.visible = false;
  280. modal.$parent.buttonLoading = false;
  281. modal.$parent.remove();
  282. },
  283. component: modal,
  284. };
  285. };
  286. export default Modal;