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 | ... | ... |