Commit 2f71cf55ccb36dc6ae4de409e7ebb8e0211cdc83
1 parent
381751c5
fixed bug $Modal
fixed bug $Modal
Showing
4 changed files
with
1 additions
and
441 deletions
Show diff stats
src/components/dialog/confirm.js deleted
1 | -import Vue from 'vue'; | ||
2 | -import Modal from './dialog.vue'; | ||
3 | -import Icon from '../icon/icon.vue'; | ||
4 | -import iButton from '../button/button.vue'; | ||
5 | -import { camelcaseToHyphen } from '../../utils/assist'; | ||
6 | - | ||
7 | -const prefixCls = 'ivu-modal-confirm'; | ||
8 | - | ||
9 | -Modal.newInstance = properties => { | ||
10 | - const _props = properties || {}; | ||
11 | - | ||
12 | - let props = ''; | ||
13 | - Object.keys(_props).forEach(prop => { | ||
14 | - props += ' :' + camelcaseToHyphen(prop) + '=' + prop; | ||
15 | - }); | ||
16 | - | ||
17 | - const div = document.createElement('div'); | ||
18 | - div.innerHTML = ` | ||
19 | - <Modal${props} :visible.sync="visible" :width="width"> | ||
20 | - <div class="${prefixCls}"> | ||
21 | - <div class="${prefixCls}-head"> | ||
22 | - <div :class="iconTypeCls"><i :class="iconNameCls"></i></div> | ||
23 | - <div class="${prefixCls}-head-title">{{{ title }}}</div> | ||
24 | - </div> | ||
25 | - <div class="${prefixCls}-body"> | ||
26 | - {{{ body }}} | ||
27 | - </div> | ||
28 | - <div class="${prefixCls}-footer"> | ||
29 | - <i-button type="ghost" size="large" v-if="showCancel" @click="cancel">{{ cancelText }}</i-button> | ||
30 | - <i-button type="primary" size="large" :loading="buttonLoading" @click="ok">{{ okText }}</i-button> | ||
31 | - </div> | ||
32 | - </div> | ||
33 | - </Modal> | ||
34 | - `; | ||
35 | - document.body.appendChild(div); | ||
36 | - | ||
37 | - const modal = new Vue({ | ||
38 | - el: div, | ||
39 | - components: { Modal, iButton, Icon }, | ||
40 | - data: Object.assign(_props, { | ||
41 | - visible: false, | ||
42 | - width: 416, | ||
43 | - title: '', | ||
44 | - body: '', | ||
45 | - iconType: '', | ||
46 | - iconName: '', | ||
47 | - okText: '确定', | ||
48 | - cancelText: '取消', | ||
49 | - showCancel: false, | ||
50 | - loading: false, | ||
51 | - buttonLoading: false | ||
52 | - }), | ||
53 | - computed: { | ||
54 | - iconTypeCls () { | ||
55 | - return [ | ||
56 | - `${prefixCls}-head-icon`, | ||
57 | - `${prefixCls}-head-icon-${this.iconType}` | ||
58 | - ] | ||
59 | - }, | ||
60 | - iconNameCls () { | ||
61 | - return [ | ||
62 | - 'ivu-icon', | ||
63 | - `ivu-icon-${this.iconName}` | ||
64 | - ] | ||
65 | - } | ||
66 | - }, | ||
67 | - methods: { | ||
68 | - cancel () { | ||
69 | - this.visible = false; | ||
70 | - this.buttonLoading = false; | ||
71 | - this.onCancel(); | ||
72 | - this.remove(); | ||
73 | - }, | ||
74 | - ok () { | ||
75 | - if (this.loading) { | ||
76 | - this.buttonLoading = true; | ||
77 | - } else { | ||
78 | - this.visible = false; | ||
79 | - this.remove(); | ||
80 | - } | ||
81 | - this.onOk(); | ||
82 | - }, | ||
83 | - remove () { | ||
84 | - setTimeout(() => { | ||
85 | - this.destroy(); | ||
86 | - }, 300); | ||
87 | - }, | ||
88 | - destroy () { | ||
89 | - this.$destroy(); | ||
90 | - document.body.removeChild(div); | ||
91 | - this.onRemove(); | ||
92 | - }, | ||
93 | - onOk () {}, | ||
94 | - onCancel () {}, | ||
95 | - onRemove () {} | ||
96 | - } | ||
97 | - }).$children[0]; | ||
98 | - | ||
99 | - return { | ||
100 | - show (props) { | ||
101 | - modal.$parent.showCancel = props.showCancel; | ||
102 | - modal.$parent.iconType = props.icon; | ||
103 | - | ||
104 | - switch (props.icon) { | ||
105 | - case 'info': | ||
106 | - modal.$parent.iconName = 'information-circled'; | ||
107 | - break; | ||
108 | - case 'success': | ||
109 | - modal.$parent.iconName = 'checkmark-circled'; | ||
110 | - break; | ||
111 | - case 'warning': | ||
112 | - modal.$parent.iconName = 'android-alert'; | ||
113 | - break; | ||
114 | - case 'error': | ||
115 | - modal.$parent.iconName = 'close-circled'; | ||
116 | - break; | ||
117 | - case 'confirm': | ||
118 | - modal.$parent.iconName = 'help-circled'; | ||
119 | - break; | ||
120 | - } | ||
121 | - | ||
122 | - if ('width' in props) { | ||
123 | - modal.$parent.width = props.width; | ||
124 | - } | ||
125 | - | ||
126 | - if ('title' in props) { | ||
127 | - modal.$parent.title = props.title; | ||
128 | - } | ||
129 | - | ||
130 | - if ('content' in props) { | ||
131 | - modal.$parent.body = props.content; | ||
132 | - } | ||
133 | - | ||
134 | - if ('okText' in props) { | ||
135 | - modal.$parent.okText = props.okText; | ||
136 | - } | ||
137 | - | ||
138 | - if ('cancelText' in props) { | ||
139 | - modal.$parent.cancelText = props.cancelText; | ||
140 | - } | ||
141 | - | ||
142 | - if ('onCancel' in props) { | ||
143 | - modal.$parent.onCancel = props.onCancel; | ||
144 | - } | ||
145 | - | ||
146 | - if ('onOk' in props) { | ||
147 | - modal.$parent.onOk = props.onOk; | ||
148 | - } | ||
149 | - | ||
150 | - // async for ok | ||
151 | - if ('loading' in props) { | ||
152 | - modal.$parent.loading = props.loading; | ||
153 | - } | ||
154 | - | ||
155 | - // notice when component destroy | ||
156 | - modal.$parent.onRemove = props.onRemove; | ||
157 | - | ||
158 | - modal.visible = true; | ||
159 | - }, | ||
160 | - remove () { | ||
161 | - modal.visible = false; | ||
162 | - modal.$parent.buttonLoading = false; | ||
163 | - modal.$parent.remove(); | ||
164 | - }, | ||
165 | - component: modal | ||
166 | - } | ||
167 | -}; | ||
168 | - | ||
169 | -export default Modal; | ||
170 | \ No newline at end of file | 0 | \ No newline at end of file |
src/components/dialog/dialog.vue deleted
1 | -<template> | ||
2 | - <div :class="wrapClasses"> | ||
3 | - <div :class="maskClasses" v-show="visible" @click="mask" transition="fade"></div> | ||
4 | - <div :class="classes" :style="styles" v-show="visible" transition="ease"> | ||
5 | - <div :class="[prefixCls + '-content']"> | ||
6 | - <a :class="[prefixCls + '-close']" v-if="closable" @click="close"> | ||
7 | - <slot name="close"> | ||
8 | - <Icon type="ios-close-empty"></Icon> | ||
9 | - </slot> | ||
10 | - </a> | ||
11 | - <div :class="[prefixCls + '-header']" v-if="showHead" v-el:head><slot name="header"><div :class="[prefixCls + '-header-inner']">{{ title }}</div></slot></div> | ||
12 | - <div :class="[prefixCls + '-body']"><slot></slot></div> | ||
13 | - <div :class="[prefixCls + '-footer']" v-if="!footerHide"> | ||
14 | - <slot name="footer"> | ||
15 | - <i-button type="ghost" size="large" @click="cancel">{{ cancelText }}</i-button> | ||
16 | - <i-button type="primary" size="large" :loading="buttonLoading" @click="ok">{{ okText }}</i-button> | ||
17 | - </slot> | ||
18 | - </div> | ||
19 | - </div> | ||
20 | - </div> | ||
21 | - </div> | ||
22 | -</template> | ||
23 | -<script> | ||
24 | - import Icon from '../icon'; | ||
25 | - import iButton from '../button/button.vue'; | ||
26 | - import { getScrollBarSize } from '../../utils/assist'; | ||
27 | - | ||
28 | - const prefixCls = 'ivu-modal'; | ||
29 | - | ||
30 | - export default { | ||
31 | - components: { Icon, iButton }, | ||
32 | - props: { | ||
33 | - visible: { | ||
34 | - type: Boolean, | ||
35 | - default: false | ||
36 | - }, | ||
37 | - closable: { | ||
38 | - type: Boolean, | ||
39 | - default: true | ||
40 | - }, | ||
41 | - maskClosable: { | ||
42 | - type: Boolean, | ||
43 | - default: true | ||
44 | - }, | ||
45 | - title: { | ||
46 | - type: String | ||
47 | - }, | ||
48 | - width: { | ||
49 | - type: [Number, String], | ||
50 | - default: 520 | ||
51 | - }, | ||
52 | - okText: { | ||
53 | - type: String, | ||
54 | - default: '确定' | ||
55 | - }, | ||
56 | - cancelText: { | ||
57 | - type: String, | ||
58 | - default: '取消' | ||
59 | - }, | ||
60 | - loading: { | ||
61 | - type: Boolean, | ||
62 | - default: false | ||
63 | - }, | ||
64 | - style: { | ||
65 | - type: Object | ||
66 | - }, | ||
67 | - className: { | ||
68 | - type: String | ||
69 | - }, | ||
70 | - // for instance | ||
71 | - footerHide: { | ||
72 | - type: Boolean, | ||
73 | - default: false | ||
74 | - } | ||
75 | - }, | ||
76 | - data () { | ||
77 | - return { | ||
78 | - prefixCls: prefixCls, | ||
79 | - wrapShow: false, | ||
80 | - showHead: true, | ||
81 | - buttonLoading: false | ||
82 | - } | ||
83 | - }, | ||
84 | - computed: { | ||
85 | - wrapClasses () { | ||
86 | - return [ | ||
87 | - `${prefixCls}-wrap`, | ||
88 | - { | ||
89 | - [`${prefixCls}-hidden`]: !this.wrapShow, | ||
90 | - [`${this.className}`]: !!this.className | ||
91 | - } | ||
92 | - ] | ||
93 | - }, | ||
94 | - maskClasses () { | ||
95 | - return `${prefixCls}-mask`; | ||
96 | - }, | ||
97 | - classes () { | ||
98 | - return `${prefixCls}`; | ||
99 | - }, | ||
100 | - styles () { | ||
101 | - let style = {}; | ||
102 | - | ||
103 | - const styleWidth = { | ||
104 | - width: `${this.width}px` | ||
105 | - }; | ||
106 | - | ||
107 | - const customStyle = !!this.style ? this.style : {}; | ||
108 | - | ||
109 | - Object.assign(style, styleWidth, customStyle); | ||
110 | - | ||
111 | - return style; | ||
112 | - } | ||
113 | - }, | ||
114 | - methods: { | ||
115 | - close () { | ||
116 | - this.visible = false; | ||
117 | - this.$emit('on-cancel'); | ||
118 | - }, | ||
119 | - mask () { | ||
120 | - if (this.maskClosable) { | ||
121 | - this.close(); | ||
122 | - } | ||
123 | - }, | ||
124 | - cancel () { | ||
125 | - this.close(); | ||
126 | - }, | ||
127 | - ok () { | ||
128 | - if (this.loading) { | ||
129 | - this.buttonLoading = true; | ||
130 | - } else { | ||
131 | - this.visible = false; | ||
132 | - } | ||
133 | - this.$emit('on-ok'); | ||
134 | - }, | ||
135 | - EscClose (e) { | ||
136 | - if (this.visible && this.closable) { | ||
137 | - if (e.keyCode === 27) { | ||
138 | - this.close() | ||
139 | - } | ||
140 | - } | ||
141 | - }, | ||
142 | - checkScrollBar () { | ||
143 | - let fullWindowWidth = window.innerWidth; | ||
144 | - if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 | ||
145 | - const documentElementRect = document.documentElement.getBoundingClientRect(); | ||
146 | - fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left); | ||
147 | - } | ||
148 | - this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth; | ||
149 | - if (this.bodyIsOverflowing) { | ||
150 | - this.scrollBarWidth = getScrollBarSize(); | ||
151 | - } | ||
152 | - }, | ||
153 | - setScrollBar () { | ||
154 | - if (this.bodyIsOverflowing && this.scrollBarWidth !== undefined) { | ||
155 | - document.body.style.paddingRight = `${this.scrollBarWidth}px`; | ||
156 | - } | ||
157 | - }, | ||
158 | - resetScrollBar () { | ||
159 | - document.body.style.paddingRight = ''; | ||
160 | - }, | ||
161 | - addScrollEffect () { | ||
162 | - this.checkScrollBar(); | ||
163 | - this.setScrollBar(); | ||
164 | - document.body.style.overflow = 'hidden'; | ||
165 | - }, | ||
166 | - removeScrollEffect() { | ||
167 | - document.body.style.overflow = ''; | ||
168 | - this.resetScrollBar(); | ||
169 | - } | ||
170 | - }, | ||
171 | - ready () { | ||
172 | - if (this.visible) { | ||
173 | - this.wrapShow = true; | ||
174 | - } | ||
175 | - | ||
176 | - let showHead = true; | ||
177 | - | ||
178 | - if (this.$els.head.innerHTML == `<div class="${prefixCls}-header-inner"></div>` && !this.title) { | ||
179 | - showHead = false; | ||
180 | - } | ||
181 | - | ||
182 | - this.showHead = showHead; | ||
183 | - | ||
184 | - // ESC close | ||
185 | - document.addEventListener('keydown', this.EscClose); | ||
186 | - }, | ||
187 | - beforeDestroy () { | ||
188 | - document.removeEventListener('keydown', this.EscClose); | ||
189 | - }, | ||
190 | - watch: { | ||
191 | - visible (val) { | ||
192 | - if (val === false) { | ||
193 | - this.buttonLoading = false; | ||
194 | - setTimeout(() => { | ||
195 | - this.wrapShow = false; | ||
196 | - }, 300); | ||
197 | - this.removeScrollEffect(); | ||
198 | - } else { | ||
199 | - this.wrapShow = true; | ||
200 | - this.addScrollEffect(); | ||
201 | - } | ||
202 | - }, | ||
203 | - loading (val) { | ||
204 | - if (!val) { | ||
205 | - this.buttonLoading = false; | ||
206 | - } | ||
207 | - } | ||
208 | - } | ||
209 | - } | ||
210 | -</script> |
src/components/dialog/index.js deleted
1 | -import Modal from './confirm'; | ||
2 | - | ||
3 | -let modalInstance; | ||
4 | - | ||
5 | -function getModalInstance () { | ||
6 | - modalInstance = modalInstance || Modal.newInstance({ | ||
7 | - closable: false, | ||
8 | - maskClosable: false, | ||
9 | - footerHide: true | ||
10 | - }); | ||
11 | - | ||
12 | - return modalInstance; | ||
13 | -} | ||
14 | - | ||
15 | -function confirm (options) { | ||
16 | - let instance = getModalInstance(); | ||
17 | - | ||
18 | - options.onRemove = function () { | ||
19 | - modalInstance = null; | ||
20 | - }; | ||
21 | - | ||
22 | - instance.show(options); | ||
23 | -} | ||
24 | - | ||
25 | -export default { | ||
26 | - info (props = {}) { | ||
27 | - props.icon = 'info'; | ||
28 | - props.showCancel = false; | ||
29 | - return confirm(props); | ||
30 | - }, | ||
31 | - success (props = {}) { | ||
32 | - props.icon = 'success'; | ||
33 | - props.showCancel = false; | ||
34 | - return confirm(props); | ||
35 | - }, | ||
36 | - warning (props = {}) { | ||
37 | - props.icon = 'warning'; | ||
38 | - props.showCancel = false; | ||
39 | - return confirm(props); | ||
40 | - }, | ||
41 | - error (props = {}) { | ||
42 | - props.icon = 'error'; | ||
43 | - props.showCancel = false; | ||
44 | - return confirm(props); | ||
45 | - }, | ||
46 | - confirm (props = {}) { | ||
47 | - props.icon = 'confirm'; | ||
48 | - props.showCancel = true; | ||
49 | - return confirm(props); | ||
50 | - }, | ||
51 | - remove () { | ||
52 | - if (!modalInstance) { // at loading status, remove after Cancel | ||
53 | - return false; | ||
54 | - } | ||
55 | - | ||
56 | - const instance = getModalInstance(); | ||
57 | - | ||
58 | - instance.remove(); | ||
59 | - } | ||
60 | -} | ||
61 | \ No newline at end of file | 0 | \ No newline at end of file |
src/index.js
@@ -9,7 +9,6 @@ import Cascader from './components/cascader'; | @@ -9,7 +9,6 @@ import Cascader from './components/cascader'; | ||
9 | import Checkbox from './components/checkbox'; | 9 | import Checkbox from './components/checkbox'; |
10 | import Circle from './components/circle'; | 10 | import Circle from './components/circle'; |
11 | import Collapse from './components/collapse'; | 11 | import Collapse from './components/collapse'; |
12 | -import Dialog from './components/dialog'; | ||
13 | import Icon from './components/icon'; | 12 | import Icon from './components/icon'; |
14 | import Input from './components/input'; | 13 | import Input from './components/input'; |
15 | import InputNumber from './components/input-number'; | 14 | import InputNumber from './components/input-number'; |
@@ -82,7 +81,7 @@ const install = function (Vue) { | @@ -82,7 +81,7 @@ const install = function (Vue) { | ||
82 | 81 | ||
83 | Vue.prototype.$Loading = LoadingBar; | 82 | Vue.prototype.$Loading = LoadingBar; |
84 | Vue.prototype.$Message = Message; | 83 | Vue.prototype.$Message = Message; |
85 | - Vue.prototype.$Modal = Dialog; | 84 | + Vue.prototype.$Modal = Modal; |
86 | Vue.prototype.$Notice = Notice; | 85 | Vue.prototype.$Notice = Notice; |
87 | }; | 86 | }; |
88 | 87 |