119228890b42eb72d493c52aef5cd68e259736c07f2048d9120790b1b2b7aa91c85aad5db280b1af2900de3e6ecc6f979d0d354d599688b00aa4c44d7a8188 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <template>
  2. <transition
  3. name="dialog-fade"
  4. @after-enter="afterEnter"
  5. @after-leave="afterLeave">
  6. <div
  7. v-show="visible"
  8. class="el-dialog__wrapper"
  9. @click.self="handleWrapperClick">
  10. <div
  11. role="dialog"
  12. :key="key"
  13. aria-modal="true"
  14. :aria-label="title || 'dialog'"
  15. :class="['el-dialog', { 'is-fullscreen': fullscreen, 'el-dialog--center': center }, customClass]"
  16. ref="dialog"
  17. :style="style">
  18. <div class="el-dialog__header">
  19. <slot name="title">
  20. <span class="el-dialog__title">{{ title }}</span>
  21. </slot>
  22. <button
  23. type="button"
  24. class="el-dialog__headerbtn"
  25. aria-label="Close"
  26. v-if="showClose"
  27. @click="handleClose">
  28. <i class="el-dialog__close el-icon el-icon-close"></i>
  29. </button>
  30. </div>
  31. <div class="el-dialog__body" v-if="rendered"><slot></slot></div>
  32. <div class="el-dialog__footer" v-if="$slots.footer">
  33. <slot name="footer"></slot>
  34. </div>
  35. </div>
  36. </div>
  37. </transition>
  38. </template>
  39. <script>
  40. import Popup from 'element-ui/src/utils/popup';
  41. import Migrating from 'element-ui/src/mixins/migrating';
  42. import emitter from 'element-ui/src/mixins/emitter';
  43. export default {
  44. name: 'ElDialog',
  45. mixins: [Popup, emitter, Migrating],
  46. props: {
  47. title: {
  48. type: String,
  49. default: ''
  50. },
  51. modal: {
  52. type: Boolean,
  53. default: true
  54. },
  55. modalAppendToBody: {
  56. type: Boolean,
  57. default: true
  58. },
  59. appendToBody: {
  60. type: Boolean,
  61. default: false
  62. },
  63. lockScroll: {
  64. type: Boolean,
  65. default: true
  66. },
  67. closeOnClickModal: {
  68. type: Boolean,
  69. default: true
  70. },
  71. closeOnPressEscape: {
  72. type: Boolean,
  73. default: true
  74. },
  75. showClose: {
  76. type: Boolean,
  77. default: true
  78. },
  79. width: String,
  80. fullscreen: Boolean,
  81. customClass: {
  82. type: String,
  83. default: ''
  84. },
  85. top: {
  86. type: String,
  87. default: '15vh'
  88. },
  89. beforeClose: Function,
  90. center: {
  91. type: Boolean,
  92. default: false
  93. },
  94. destroyOnClose: Boolean
  95. },
  96. data() {
  97. return {
  98. closed: false,
  99. key: 0
  100. };
  101. },
  102. watch: {
  103. visible(val) {
  104. if (val) {
  105. this.closed = false;
  106. this.$emit('open');
  107. this.$el.addEventListener('scroll', this.updatePopper);
  108. this.$nextTick(() => {
  109. this.$refs.dialog.scrollTop = 0;
  110. });
  111. if (this.appendToBody) {
  112. document.body.appendChild(this.$el);
  113. }
  114. } else {
  115. this.$el.removeEventListener('scroll', this.updatePopper);
  116. if (!this.closed) this.$emit('close');
  117. if (this.destroyOnClose) {
  118. this.$nextTick(() => {
  119. this.key++;
  120. });
  121. }
  122. }
  123. }
  124. },
  125. computed: {
  126. style() {
  127. let style = {};
  128. if (!this.fullscreen) {
  129. style.marginTop = this.top;
  130. if (this.width) {
  131. style.width = this.width;
  132. }
  133. }
  134. return style;
  135. }
  136. },
  137. methods: {
  138. getMigratingConfig() {
  139. return {
  140. props: {
  141. 'size': 'size is removed.'
  142. }
  143. };
  144. },
  145. handleWrapperClick() {
  146. if (!this.closeOnClickModal) return;
  147. this.handleClose();
  148. },
  149. handleClose() {
  150. if (typeof this.beforeClose === 'function') {
  151. this.beforeClose(this.hide);
  152. } else {
  153. this.hide();
  154. }
  155. },
  156. hide(cancel) {
  157. if (cancel !== false) {
  158. this.$emit('update:visible', false);
  159. this.$emit('close');
  160. this.closed = true;
  161. }
  162. },
  163. updatePopper() {
  164. this.broadcast('ElSelectDropdown', 'updatePopper');
  165. this.broadcast('ElDropdownMenu', 'updatePopper');
  166. },
  167. afterEnter() {
  168. this.$emit('opened');
  169. },
  170. afterLeave() {
  171. this.$emit('closed');
  172. }
  173. },
  174. mounted() {
  175. if (this.visible) {
  176. this.rendered = true;
  177. this.open();
  178. if (this.appendToBody) {
  179. document.body.appendChild(this.$el);
  180. }
  181. }
  182. },
  183. destroyed() {
  184. // if appendToBody is true, remove DOM node after destroy
  185. if (this.appendToBody && this.$el && this.$el.parentNode) {
  186. this.$el.parentNode.removeChild(this.$el);
  187. }
  188. }
  189. };
  190. </script>