index.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <template>
  2. <Suspense v-if="isBody">
  3. <Teleport :to="`#${toId}`">
  4. <el-drawer ref="drawerRef" :modal-class="uis" :class="`hc-drawer-box ${ui}`" v-model="isShow" :with-header="false" :direction="direction" :size="size" destroy-on-close @closed="drawerClosed">
  5. <HcCard :title="title" :extraText="extraText" :actionSize="actionSize" :scrollbar="scrollbar" :actionUi="actionUi" v-if="isCard">
  6. <template #header v-if="isSlotHeader">
  7. <slot name='header'/>
  8. </template>
  9. <template #extra v-if="isSlotExtra">
  10. <slot name='extra'/>
  11. </template>
  12. <template #search v-if="isSlotSearchBar">
  13. <slot name='search'/>
  14. </template>
  15. <template #action v-if="isSlotAction">
  16. <slot name='action'/>
  17. </template>
  18. <slot></slot>
  19. </HcCard>
  20. <slot v-if="!isCard"></slot>
  21. </el-drawer>
  22. </Teleport>
  23. </Suspense>
  24. </template>
  25. <script setup>
  26. import {ref, nextTick, watch, useSlots} from "vue";
  27. const props = defineProps({
  28. uis: {
  29. type: String,
  30. default: ''
  31. },
  32. ui: {
  33. type: String,
  34. default: ''
  35. },
  36. show: {
  37. type: Boolean,
  38. default: false
  39. },
  40. toId: {
  41. type: [String,Number],
  42. default: ''
  43. },
  44. title: {
  45. type: [String,Number],
  46. default: ''
  47. },
  48. //rtl / ltr / ttb / btt
  49. direction: {
  50. type: String,
  51. default: 'ttb'
  52. },
  53. scrollbar: {
  54. type: Boolean,
  55. default: false
  56. },
  57. extraText: {
  58. type: [String,Number],
  59. default: ''
  60. },
  61. actionSize: {
  62. type: [String,Number],
  63. default: 'lg'
  64. },
  65. size: {
  66. type: [String,Number],
  67. default: '100%'
  68. },
  69. isCard: {
  70. type: Boolean,
  71. default: true
  72. },
  73. actionUi: {
  74. type: String,
  75. default: ''
  76. },
  77. })
  78. //变量
  79. const isShow = ref(props.show)
  80. const isBody = ref(false)
  81. //监听
  82. watch(() => [
  83. props.show
  84. ], ([show]) => {
  85. isShow.value = show
  86. })
  87. //渲染完成
  88. nextTick(()=> {
  89. //页面渲染完成后,再让 vue3 的 Teleport,挂载到指定节点
  90. isBody.value = true
  91. })
  92. //判断<slot>是否有传值
  93. const slots = useSlots()
  94. const isSlotHeader = ref(!!slots.header);
  95. const isSlotExtra = ref(!!slots.extra);
  96. const isSlotAction = ref(!!slots.action);
  97. const isSlotSearchBar = ref(!!slots.search);
  98. const drawerRef = ref(null)
  99. const emit = defineEmits(['close'])
  100. //关闭
  101. const drawerClosed = () => {
  102. isShow.value = false
  103. emit('close', false)
  104. }
  105. const handleClose = () => {
  106. drawerRef.value?.handleClose()
  107. }
  108. // 暴露出去
  109. defineExpose({
  110. handleClose
  111. })
  112. </script>
  113. <style lang="scss">
  114. .hc-card-box.el-card .el-card__body .hc-card-main-box .el-overlay {
  115. position: absolute;
  116. .hc-drawer-box.el-drawer {
  117. background-color: transparent;
  118. box-shadow: initial;
  119. .el-drawer__body {
  120. padding: 24px;
  121. overflow: hidden;
  122. .data-fill-list-box .el-collapse .el-collapse-item__wrap .el-collapse-item__content .data-fill-list-item-content {
  123. height: calc(100vh - 545px);
  124. }
  125. }
  126. }
  127. }
  128. </style>