CzrDialog.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <template>
  2. <el-dialog
  3. :style="`
  4. --czr-dialog_height: ${height};
  5. --czr-dialog_max-height: ${maxHeight};
  6. --czr-dialog_min-height: ${minHeight};
  7. `"
  8. :modal-class="`
  9. ${state.uuid}
  10. __czr-dialog ${maxHeight === 'unset' ? '' : '__czr-dialog-auto-height'} ${hiddenStyle ? '__czr-dialog-hidden-style' : ''}
  11. `"
  12. v-bind="$attrs"
  13. v-model="state.showDialog"
  14. :title="title"
  15. :width="width"
  16. align-center
  17. :before-close="beforeClose"
  18. :show-close="false"
  19. :append-to-body="isValue($attrs.appendToBody) ? $attrs.appendToBody : true"
  20. :close-on-click-modal="closeOnClickModal"
  21. :close-on-press-escape="closeOnPressEscape"
  22. >
  23. <template #header>
  24. <div class="_czr-dialog-head" v-if="title">
  25. <div class="__cdh-title">{{ title }}</div>
  26. <div class="__cdh-slot">
  27. <slot name="head" />
  28. </div>
  29. <div class="__cdh-close __hover" @click="CDClose()">
  30. <SvgIcon name="czr_close" size="16" color="#303133" />
  31. </div>
  32. </div>
  33. </template>
  34. <div
  35. class="__czr-dialog-main"
  36. :class="{ isFull: full !== false }"
  37. v-loading="loading"
  38. >
  39. <div
  40. class="__czr-dialog-content"
  41. :class="{ 'no-foot': !(showClose || showSubmit) }"
  42. >
  43. <slot />
  44. </div>
  45. <div
  46. class="__czr-dialog-foot"
  47. :style="`justify-content: ${footAlign};`"
  48. v-if="showSubmit || showClose || $slots.foot"
  49. >
  50. <slot name="foot" :close="CDClose" :submit="CDSubmit" />
  51. <template v-if="footAlign === 'center'">
  52. <div
  53. v-if="showSubmit"
  54. class="__czr-dialog-foot_submit __hover"
  55. @click="CDSubmit"
  56. >
  57. {{ submitText }}
  58. </div>
  59. <div
  60. v-if="showClose"
  61. class="__czr-dialog-foot_cancel __hover"
  62. @click="CDClose()"
  63. >
  64. {{ closeText }}
  65. </div>
  66. </template>
  67. <template v-else>
  68. <div
  69. v-if="showClose"
  70. class="__czr-dialog-foot_cancel __hover"
  71. @click="CDClose()"
  72. >
  73. {{ closeText }}
  74. </div>
  75. <div
  76. v-if="showSubmit"
  77. class="__czr-dialog-foot_submit __hover"
  78. @click="CDSubmit"
  79. >
  80. {{ submitText }}
  81. </div>
  82. </template>
  83. </div>
  84. </div>
  85. </el-dialog>
  86. </template>
  87. <script setup lang="ts">
  88. defineOptions({
  89. name: 'CzrDialog',
  90. })
  91. import { isValue } from '@/utils/czr-util'
  92. import { computed, onMounted, reactive, watch } from 'vue'
  93. import { ElMessage, ElMessageBox } from 'element-plus'
  94. import { v4 } from 'uuid'
  95. import { useDialogStore } from '@/stores'
  96. const emit = defineEmits(['onSubmit', 'update:show', 'onClose'])
  97. const props = defineProps({
  98. show: { required: true, type: Boolean },
  99. title: { default: '' },
  100. width: { default: '50%' },
  101. full: { default: false },
  102. submitText: { default: '确定' },
  103. closeText: { default: '取消' },
  104. showClose: { default: true },
  105. showSubmit: { default: true },
  106. footAlign: { default: 'center' },
  107. // footPadding: {default: '16px 26px'},
  108. height: { default: 'auto' },
  109. maxHeight: { default: 'unset' },
  110. minHeight: { default: 'unset' },
  111. closeOnClickModal: { default: false },
  112. closeOnPressEscape: { default: false },
  113. closeConfirm: { default: false },
  114. closeConfirmText: {
  115. default: {
  116. title: null,
  117. message: null,
  118. submit: null,
  119. close: null,
  120. },
  121. },
  122. loading: {
  123. default: false,
  124. type: Boolean,
  125. },
  126. hiddenStyle: {
  127. default: false,
  128. },
  129. })
  130. const DialogLevelStore = useDialogStore()
  131. const state = reactive({
  132. showDialog: false,
  133. closeConfirmTextTemp: {
  134. title: '提示',
  135. message: '请确认是否关闭?',
  136. submit: '确定',
  137. close: '取消',
  138. },
  139. uuid: v4(),
  140. })
  141. watch(
  142. () => props.show,
  143. (n) => {
  144. state.showDialog = n
  145. if (n) {
  146. DialogLevelStore.add(state.uuid)
  147. } else {
  148. DialogLevelStore.del(state.uuid)
  149. }
  150. },
  151. )
  152. const beforeClose = (done) => {
  153. CDClose(done)
  154. }
  155. const closeConfirmTextCpt: any = computed(() => {
  156. return {
  157. title: isValue(props.closeConfirmText.title)
  158. ? props.closeConfirmText.title
  159. : state.closeConfirmTextTemp.title,
  160. message: isValue(props.closeConfirmText.message)
  161. ? props.closeConfirmText.message
  162. : state.closeConfirmTextTemp.message,
  163. submit: isValue(props.closeConfirmText.submit)
  164. ? props.closeConfirmText.submit
  165. : state.closeConfirmTextTemp.submit,
  166. close: isValue(props.closeConfirmText.close)
  167. ? props.closeConfirmText.close
  168. : state.closeConfirmTextTemp.close,
  169. }
  170. })
  171. const CDClose = async (done = () => {}) => {
  172. if (props.closeConfirm !== false) {
  173. await ElMessageBox.confirm(
  174. closeConfirmTextCpt.value.message,
  175. closeConfirmTextCpt.value.title,
  176. {
  177. confirmButtonText: closeConfirmTextCpt.value.submit,
  178. cancelButtonText: closeConfirmTextCpt.value.close,
  179. type: 'warning',
  180. },
  181. )
  182. .then(() => {
  183. emit('update:show', false)
  184. emit('onClose')
  185. done()
  186. })
  187. .catch(() => {})
  188. } else {
  189. emit('update:show', false)
  190. emit('onClose')
  191. done()
  192. }
  193. }
  194. const CDSubmit = () => {
  195. emit('onSubmit')
  196. }
  197. onMounted(() => {
  198. state.showDialog = props.show
  199. })
  200. </script>
  201. <style scoped lang="scss"></style>