deptItem.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <template>
  2. <div class="ibox">
  3. <el-popover placement="top" trigger="click">
  4. <div class="floatdiv">
  5. <template v-if="data.root"> 123 </template>
  6. <template v-else>
  7. <el-button size="mini" @click="updData('0', data)">添加</el-button>
  8. <el-button size="mini" @click="updData('1', data)">修改</el-button>
  9. <el-button size="mini" @click="delData(data)">删除</el-button>
  10. </template>
  11. </div>
  12. <span class="title" ref="title" slot="reference" :class="{ shu: !data.children || !data.children }">{{ data.label }}</span>
  13. </el-popover>
  14. <div class="line" v-if="data.children && data.children.length != 0">
  15. <div class="top" ref="top">
  16. <div class="topline"></div>
  17. </div>
  18. <div class="center" ref="center"></div>
  19. <div class="bottom" ref="bottom" v-for="i in point" :key="i + '' + Math.random() + '' + Math.random()" :style="{ left: i + 'px' }"></div>
  20. </div>
  21. <div class="inner">
  22. <div class="innerbox" ref="box" :style="{ marginRight: mr + 'px' }" v-for="item in data.children" :key="item.id + 'a'">
  23. <DeptItem :data="item" />
  24. </div>
  25. </div>
  26. </div>
  27. </template>
  28. <script>
  29. export default {
  30. name: 'DeptItem',
  31. props: {
  32. data: Object
  33. },
  34. data() {
  35. return {
  36. point: [],
  37. mr: 20
  38. }
  39. },
  40. inject: ['updData', 'delData', 'resetDel'],
  41. mounted() {
  42. this.getPos()
  43. },
  44. methods: {
  45. getPos() {
  46. this.$nextTick(() => {
  47. let box = this.$refs.box
  48. if (!box || box.length == 0) return
  49. let center = this.$refs.center
  50. let top = this.$refs.top
  51. let title = this.$refs.title
  52. this.point = []
  53. let centerWidth = box[0].offsetWidth / 2 + box[box.length - 1].offsetWidth / 2 + (box.length - 1) * this.mr
  54. box.forEach((item, index) => {
  55. if (index != 0 && index != box.length - 1) {
  56. centerWidth += item.offsetWidth
  57. }
  58. this.point.push(item.offsetLeft + item.offsetWidth / 2)
  59. })
  60. if (box.length == 1) {
  61. centerWidth = 1
  62. }
  63. center.style.width = centerWidth + 'px'
  64. center.style.left = box[0].offsetWidth / 2 + 'px'
  65. top.style.left = centerWidth / 2 + box[0].offsetWidth / 2 - 10 + 'px'
  66. top.style.marginLeft = 0
  67. let titleLeft = centerWidth / 2 + box[0].offsetWidth / 2 - title.offsetWidth / 2
  68. titleLeft = titleLeft < 0 ? 0 : titleLeft
  69. title.style.left = titleLeft + 'px'
  70. })
  71. if (this.$parent.$el.className == 'ibox') {
  72. this.$parent.getPos()
  73. }
  74. }
  75. }
  76. }
  77. </script>
  78. <style scoped lang="scss">
  79. .ibox {
  80. width: 100%;
  81. position: relative;
  82. display: inline-block;
  83. font-size: 16px;
  84. }
  85. .ibox span.title {
  86. display: inline-block;
  87. width: auto;
  88. height: 40px;
  89. line-height: 40px;
  90. padding: 0 10px;
  91. background-color: #199ed8;
  92. border-radius: 5px;
  93. position: relative;
  94. top: 0;
  95. left: 0;
  96. cursor: pointer;
  97. user-select: none;
  98. white-space: nowrap;
  99. color: #fff;
  100. margin: 0;
  101. }
  102. .ibox span.shu {
  103. word-wrap: break-word;
  104. word-break: break-all;
  105. white-space: normal;
  106. width: 16px;
  107. height: auto;
  108. line-height: 26px;
  109. padding: 10px;
  110. text-align: center;
  111. box-sizing: content-box;
  112. }
  113. .ibox .inner {
  114. width: 100%;
  115. vertical-align: top;
  116. }
  117. .ibox .innerbox {
  118. display: inline-block;
  119. position: relative;
  120. vertical-align: top;
  121. }
  122. .line {
  123. position: relative;
  124. width: 100%;
  125. height: 61px;
  126. }
  127. .line .top {
  128. position: relative;
  129. width: 20px;
  130. top: 0;
  131. }
  132. .line .top .topline {
  133. position: absolute;
  134. width: 1px;
  135. height: 21px;
  136. left: 50%;
  137. transform: translateX(-50%);
  138. background-color: #2538ff;
  139. }
  140. .line .center {
  141. position: absolute;
  142. top: 21px;
  143. height: 1px;
  144. background-color: #2538ff;
  145. }
  146. .line .bottom {
  147. position: absolute;
  148. height: 42px;
  149. width: 1px;
  150. background-color: #2538ff;
  151. top: 22px;
  152. }
  153. .floatdiv {
  154. white-space: nowrap;
  155. text-align: center;
  156. padding: 0;
  157. }
  158. .floatdiv button {
  159. padding: 5px 10px;
  160. }
  161. </style>