cb6c471e83fa389d724cff3265f294c8ef5c9ee2.svn-base 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <a-popover :visible="visible" :placement="placement" overlayClassName="j-vxe-popover-overlay" :overlayStyle="overlayStyle">
  3. <div class="j-vxe-popover-title" slot="title">
  4. <div>子表</div>
  5. <div class="j-vxe-popover-title-close" @click="close">
  6. <a-icon type="close"/>
  7. </div>
  8. </div>
  9. <template slot="content">
  10. <transition name="fade">
  11. <slot v-if="visible" name="subForm" :row="row" :column="column"/>
  12. </transition>
  13. </template>
  14. <div ref="div" class="j-vxe-popover-div"></div>
  15. </a-popover>
  16. </template>
  17. <script>
  18. import domAlign from 'dom-align'
  19. import { getParentNodeByTagName } from '../utils/vxeUtils'
  20. import { cloneObject, triggerWindowResizeEvent } from '@/utils/util'
  21. export default {
  22. name: 'JVxeSubPopover',
  23. data() {
  24. return {
  25. visible: false,
  26. // 当前行
  27. row: null,
  28. column: null,
  29. overlayStyle: {
  30. width: null,
  31. zIndex: 100
  32. },
  33. placement: 'bottom'
  34. }
  35. },
  36. created() {
  37. },
  38. methods: {
  39. toggle(event) {
  40. //update-begin-author:taoyan date:20200921 for: 弹出子表时,子表会闪一下,类似重新计算子表的位置
  41. if(document.body.clientHeight - event.$event.clientY > 350){
  42. this.placement = 'bottom'
  43. }else{
  44. this.placement = 'top'
  45. }
  46. //update-end-author:taoyan date:20200921 for: 弹出子表时,子表会闪一下,类似重新计算子表的位置
  47. if (this.row == null) {
  48. this.open(event)
  49. } else {
  50. this.row.id === event.row.id ? this.close() : this.reopen(event)
  51. }
  52. },
  53. open(event, level = 0) {
  54. if (level > 3) {
  55. this.$message.error('打开子表失败')
  56. console.warn('【JVxeSubPopover】打开子表失败')
  57. return
  58. }
  59. let {row, column, $table, $event: {target}} = event
  60. this.row = cloneObject(row)
  61. this.column = column
  62. let className = target.className || ''
  63. className = typeof className === 'string' ? className : className.toString()
  64. // 点击的是expand,不做处理
  65. if (className.includes('vxe-table--expand-btn')) {
  66. return
  67. }
  68. // 点击的是checkbox,不做处理
  69. if (className.includes('vxe-checkbox--icon') || className.includes('vxe-cell--checkbox')) {
  70. return
  71. }
  72. // 点击的是radio,不做处理
  73. if (className.includes('vxe-radio--icon') || className.includes('vxe-cell--radio')) {
  74. return
  75. }
  76. let table = $table.$el
  77. let tr = getParentNodeByTagName(target, 'tr')
  78. if (table && tr) {
  79. let clientWidth = table.clientWidth
  80. let clientHeight = tr.clientHeight
  81. this.$refs.div.style.width = clientWidth + 'px'
  82. this.$refs.div.style.height = clientHeight + 'px'
  83. this.overlayStyle.width = Number.parseInt((clientWidth - clientWidth * 0.04)) + 'px'
  84. this.overlayStyle.maxWidth = this.overlayStyle.width
  85. //update-begin-author:taoyan date:20200921 for: 子表弹出位置存在现实位置问题。
  86. //let realTable = getParentNodeByTagName(tr, 'table')
  87. //let left = realTable.parentNode.scrollLeft
  88. let h = event.$event.clientY
  89. if(h){
  90. h = h-140
  91. }
  92. let toolbar = this.$refs.div.nextSibling
  93. domAlign(this.$refs.div, toolbar, {
  94. points: ['tl', 'tl'],
  95. offset: [0, h],
  96. overflow: {
  97. alwaysByViewport: true
  98. },
  99. })
  100. //update-end-author:taoyan date:20200921 for: 子表弹出位置存在现实位置问题。
  101. this.$nextTick(() => {
  102. this.visible = true
  103. this.$nextTick(() => {
  104. triggerWindowResizeEvent()
  105. })
  106. })
  107. } else {
  108. let num = ++level
  109. console.warn('【JVxeSubPopover】table or tr 获取失败,正在进行第 ' + num + '次重试', {event, table, tr})
  110. window.setTimeout(() => this.open(event, num), 100)
  111. }
  112. },
  113. close() {
  114. if (this.visible) {
  115. this.row = null
  116. this.visible = false
  117. }
  118. },
  119. reopen(event) {
  120. this.close()
  121. this.open(event)
  122. },
  123. },
  124. }
  125. </script>
  126. <style scoped lang="less">
  127. .j-vxe-popover-title {
  128. .j-vxe-popover-title-close {
  129. position: absolute;
  130. right: 0;
  131. top: 0;
  132. width: 31px;
  133. height: 31px;
  134. text-align: center;
  135. line-height: 31px;
  136. color: rgba(0, 0, 0, 0.45);
  137. cursor: pointer;
  138. transition: color 300ms;
  139. &:hover {
  140. color: rgba(0, 0, 0, 0.8);
  141. }
  142. }
  143. }
  144. .j-vxe-popover-div {
  145. position: absolute;
  146. top: 0;
  147. left: 0;
  148. width: 100%;
  149. height: 31px;
  150. z-index: -1;
  151. }
  152. </style>
  153. <style lang="less">
  154. .j-vxe-popover-overlay.ant-popover {
  155. .ant-popover-title {
  156. position: relative;
  157. }
  158. }
  159. .fade-enter-active,
  160. .fade-leave-active {
  161. opacity: 1;
  162. transition: opacity 0.5s;
  163. }
  164. .fade-enter,
  165. .fade-leave-to {
  166. opacity: 0;
  167. }
  168. </style>