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 | 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 | 0 | \ No newline at end of file |
src/index.js
... | ... | @@ -9,7 +9,6 @@ import Cascader from './components/cascader'; |
9 | 9 | import Checkbox from './components/checkbox'; |
10 | 10 | import Circle from './components/circle'; |
11 | 11 | import Collapse from './components/collapse'; |
12 | -import Dialog from './components/dialog'; | |
13 | 12 | import Icon from './components/icon'; |
14 | 13 | import Input from './components/input'; |
15 | 14 | import InputNumber from './components/input-number'; |
... | ... | @@ -82,7 +81,7 @@ const install = function (Vue) { |
82 | 81 | |
83 | 82 | Vue.prototype.$Loading = LoadingBar; |
84 | 83 | Vue.prototype.$Message = Message; |
85 | - Vue.prototype.$Modal = Dialog; | |
84 | + Vue.prototype.$Modal = Modal; | |
86 | 85 | Vue.prototype.$Notice = Notice; |
87 | 86 | }; |
88 | 87 | ... | ... |