index.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <!--
  2. 移动端 底部弹出对话框 组件
  3. - pc 端,仅展示【插槽】内容,无弹出对话框,无对话框相关 header footer
  4. - mobile 端,底部弹出对话框,支持 对话框相关 header footer 定制展示,详情请参见参数列表
  5. -->
  6. <template>
  7. <div v-if="props.show">
  8. <div
  9. v-if="!isPC"
  10. :class="[
  11. 'bottom-popup',
  12. isUniFrameWork && 'bottom-popup-uni',
  13. !isPC && 'bottom-popup-h5',
  14. !isPC && props.modal && 'bottom-popup-modal',
  15. ]"
  16. @click="closeBottomPopup"
  17. >
  18. <div
  19. ref="dialogRef"
  20. :class="['bottom-popup-main', !isPC && 'bottom-popup-h5-main']"
  21. :style="{
  22. height: props.height,
  23. borderTopLeftRadius: props.borderRadius,
  24. borderTopRightRadius: props.borderRadius,
  25. }"
  26. @click.stop
  27. >
  28. <div
  29. v-if="title || showHeaderCloseButton"
  30. class="header"
  31. >
  32. <div
  33. v-if="title"
  34. class="header-title"
  35. >
  36. {{ title }}
  37. </div>
  38. <div
  39. v-if="showHeaderCloseButton"
  40. class="header-close"
  41. @click="closeBottomPopup"
  42. >
  43. {{ TUITranslateService.t("关闭") }}
  44. </div>
  45. </div>
  46. <slot />
  47. <div
  48. v-if="showFooterSubmitButton"
  49. class="footer"
  50. >
  51. <div
  52. class="footer-submit"
  53. @click="submit"
  54. >
  55. {{ submitButtonContent }}
  56. </div>
  57. </div>
  58. </div>
  59. </div>
  60. <slot v-else />
  61. </div>
  62. </template>
  63. <script setup lang="ts">
  64. import { ref, watch, nextTick } from '../../../adapter-vue';
  65. import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
  66. import { outsideClick } from '@tencentcloud/universal-api';
  67. import { isPC, isH5, isUniFrameWork } from '../../../utils/env';
  68. const props = defineProps({
  69. // Whether to display the bottom pop-up dialog box
  70. show: {
  71. type: Boolean,
  72. default: false,
  73. },
  74. // Whether a mask layer is required, the default is true
  75. modal: {
  76. type: Boolean,
  77. default: true,
  78. },
  79. // Popup box content area height (excluding mask), default is fit-content
  80. height: {
  81. type: String,
  82. default: 'fit-content',
  83. },
  84. // Whether the pop-up dialog box can be closed by clicking outside, the default is true
  85. // uniapp only supports closing the pop-up dialog box by clicking the mask
  86. closeByClickOutside: {
  87. type: Boolean,
  88. default: true,
  89. },
  90. // The rounded angle of the top border corners is 0px by default, i.e. right angle by default
  91. borderRadius: {
  92. type: String,
  93. default: '0px',
  94. },
  95. title: {
  96. type: String,
  97. default: '',
  98. },
  99. // Whether to display the top close button, not displayed by default
  100. showHeaderCloseButton: {
  101. type: Boolean,
  102. default: false,
  103. },
  104. // Whether to display the submit button at the bottom, not displayed by default
  105. showFooterSubmitButton: {
  106. type: Boolean,
  107. default: false,
  108. },
  109. // Bottom submit button text, only valid when showFooterSubmitButton is true
  110. submitButtonContent: {
  111. type: String,
  112. default: () => TUITranslateService.t('确定'),
  113. },
  114. });
  115. const emits = defineEmits(['onOpen', 'onClose', 'onSubmit']);
  116. const dialogRef = ref();
  117. watch(
  118. () => props.show,
  119. (newVal: boolean, oldVal: boolean) => {
  120. if (newVal === oldVal) {
  121. return;
  122. }
  123. switch (newVal) {
  124. case true:
  125. emits('onOpen', dialogRef);
  126. nextTick(() => {
  127. // Effective under web h5
  128. if (isH5 && !isUniFrameWork) {
  129. if (props.closeByClickOutside) {
  130. outsideClick.listen({
  131. domRefs: dialogRef.value,
  132. handler: closeBottomPopup,
  133. });
  134. }
  135. }
  136. });
  137. break;
  138. case false:
  139. emits('onClose', dialogRef);
  140. break;
  141. }
  142. },
  143. );
  144. const closeBottomPopup = () => {
  145. if (isUniFrameWork || isH5) {
  146. emits('onClose', dialogRef);
  147. }
  148. };
  149. const submit = () => {
  150. emits('onSubmit');
  151. closeBottomPopup();
  152. };
  153. </script>
  154. <style scoped lang="scss" src="./style/index.scss"></style>