CostAuditDialog.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <template>
  2. <el-dialog
  3. :title="title"
  4. :visible="visible"
  5. :width="width"
  6. :top="top"
  7. :modal="modal"
  8. :modal-append-to-body="modalAppendToBody"
  9. :append-to-body="appendToBody"
  10. :lock-scroll="lockScroll"
  11. :custom-class="customClass"
  12. :close-on-click-modal="closeOnClickModal"
  13. :close-on-press-escape="closeOnPressEscape"
  14. :show-close="showClose"
  15. :before-close="handleBeforeClose"
  16. v-bind="mergedDialogProps"
  17. :style="{ minWidth: '650px' }"
  18. @open="handleOpen"
  19. @close="handleClose"
  20. @closed="handleClosed"
  21. >
  22. <!-- 弹窗内容 -->
  23. <div class="dialog-content">
  24. <slot></slot>
  25. </div>
  26. <!-- 弹窗底部按钮 -->
  27. <div v-if="showFooter" slot="footer" class="dialog-footer">
  28. <slot name="footer">
  29. <el-button
  30. v-if="showConfirmBtn"
  31. :type="confirmBtnType"
  32. :loading="confirmLoading"
  33. :disabled="confirmDisabled"
  34. @click="handleConfirm"
  35. >
  36. {{ confirmText }}
  37. </el-button>
  38. <el-button @click="handleCancel">
  39. {{ cancelText }}
  40. </el-button>
  41. </slot>
  42. </div>
  43. </el-dialog>
  44. </template>
  45. <script>
  46. import PopupManager from 'element-ui/lib/utils/popup'
  47. export default {
  48. name: 'CostAuditDialog',
  49. props: {
  50. // 弹窗标题
  51. title: {
  52. type: String,
  53. default: '提示',
  54. },
  55. // 弹窗是否可见
  56. visible: {
  57. type: Boolean,
  58. default: false,
  59. },
  60. // 弹窗宽度
  61. width: {
  62. type: String,
  63. default: '50%',
  64. },
  65. // 弹窗距离顶部的距离
  66. top: {
  67. type: String,
  68. default: '15vh',
  69. },
  70. // 是否显示遮罩
  71. modal: {
  72. type: Boolean,
  73. default: true,
  74. },
  75. // 遮罩是否插入至body元素上
  76. modalAppendToBody: {
  77. type: Boolean,
  78. default: true,
  79. },
  80. // 弹窗是否插入至body元素上
  81. appendToBody: {
  82. type: Boolean,
  83. default: true,
  84. },
  85. // 是否在显示弹窗时将body滚动锁定
  86. lockScroll: {
  87. type: Boolean,
  88. default: true,
  89. },
  90. // 自定义类名
  91. customClass: {
  92. type: String,
  93. default: '',
  94. },
  95. // 是否可以通过点击遮罩关闭弹窗
  96. closeOnClickModal: {
  97. type: Boolean,
  98. default: true,
  99. },
  100. // 是否可以通过按下ESC键关闭弹窗
  101. closeOnPressEscape: {
  102. type: Boolean,
  103. default: true,
  104. },
  105. // 是否显示关闭按钮
  106. showClose: {
  107. type: Boolean,
  108. default: true,
  109. },
  110. // 是否显示确认按钮
  111. showConfirmBtn: {
  112. type: Boolean,
  113. default: true,
  114. },
  115. // 确认按钮文本
  116. confirmText: {
  117. type: String,
  118. default: '确认',
  119. },
  120. // 取消按钮文本
  121. cancelText: {
  122. type: String,
  123. default: '取消',
  124. },
  125. // 确认按钮类型
  126. confirmBtnType: {
  127. type: String,
  128. default: 'primary',
  129. },
  130. // 确认按钮加载状态
  131. confirmLoading: {
  132. type: Boolean,
  133. default: false,
  134. },
  135. // 确认按钮是否禁用
  136. confirmDisabled: {
  137. type: Boolean,
  138. default: false,
  139. },
  140. // 额外的弹窗属性
  141. dialogProps: {
  142. type: Object,
  143. default: () => ({}),
  144. },
  145. // 弹窗层级
  146. zIndex: {
  147. type: Number,
  148. default: 2000,
  149. },
  150. // 是否显示底部按钮
  151. showFooter: {
  152. type: Boolean,
  153. default: true,
  154. },
  155. },
  156. data() {
  157. return {
  158. currentZIndex: 2000,
  159. }
  160. },
  161. computed: {
  162. mergedDialogProps() {
  163. return {
  164. ...this.dialogProps,
  165. // 保留用户传入的值,不硬编码覆盖
  166. 'modal-append-to-body': this.modalAppendToBody,
  167. 'append-to-body': this.appendToBody,
  168. }
  169. },
  170. effectiveZIndex() {
  171. // 确保返回的zIndex值总是有效且足够大
  172. return this.currentZIndex || this.zIndex || 2000
  173. },
  174. },
  175. methods: {
  176. // 处理弹窗打开前的钩子
  177. handleBeforeClose(done) {
  178. this.$emit('cancel')
  179. },
  180. // 处理弹窗打开
  181. handleOpen() {
  182. // 打开时获取下一个可用的全局zIndex,确保位于最顶层
  183. try {
  184. const next =
  185. PopupManager && typeof PopupManager.nextZIndex === 'function'
  186. ? PopupManager.nextZIndex()
  187. : this.zIndex || 2000
  188. // 如果外部已传更高的zIndex,则取更高值
  189. this.currentZIndex = Math.max(next, this.zIndex || 0)
  190. } catch (e) {
  191. this.currentZIndex = this.zIndex || 2000
  192. }
  193. this.$emit('open')
  194. },
  195. // 处理弹窗关闭
  196. handleClose() {
  197. this.$emit('update:visible', false)
  198. this.$emit('close')
  199. },
  200. // 处理弹窗关闭后的钩子
  201. handleClosed() {
  202. this.$emit('closed')
  203. },
  204. // 处理确认按钮点击
  205. handleConfirm() {
  206. this.$emit('confirm')
  207. },
  208. // 处理取消按钮点击
  209. handleCancel() {
  210. this.$emit('cancel')
  211. },
  212. // 手动关闭弹窗
  213. close() {
  214. this.$emit('update:visible', false)
  215. },
  216. // 手动打开弹窗
  217. open() {
  218. this.$emit('update:visible', true)
  219. },
  220. },
  221. }
  222. </script>
  223. <style scoped>
  224. .dialog-content {
  225. min-height: 50px;
  226. max-height: 520px;
  227. overflow-y: auto;
  228. overflow-x: hidden;
  229. }
  230. .dialog-footer {
  231. text-align: right;
  232. }
  233. </style>