ElementTierEdit.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <template>
  2. <div class="element-tier-edit">
  3. <div class="tier-menu">
  4. <div
  5. v-for="(column, cindex) in curPage.columns"
  6. :key="column.id"
  7. :class="['tier-menu-item', { 'is-active': column.id === curColumn.id }]"
  8. @click="selectColumn(column)"
  9. >
  10. 栏{{ cindex + 1 }}
  11. </div>
  12. </div>
  13. <div
  14. ref="TierList"
  15. class="tier-list"
  16. @drop.prevent="dropInnerElement"
  17. @dragover.prevent="dragOver($event)"
  18. @dragleave.prevent
  19. >
  20. <div
  21. v-for="element in curColumn.elements"
  22. :key="element.id"
  23. :class="[
  24. 'tier-item',
  25. {
  26. 'after-drop': element.id === curDropElementId && isDragDown,
  27. 'before-drop': element.id === curDropElementId && !isDragDown
  28. }
  29. ]"
  30. :id="`tier-${element.id}`"
  31. draggable="true"
  32. @dragstart="$event => dragStart($event, element)"
  33. @dragend.prevent="dragEnd"
  34. @click="selectElement(element)"
  35. >
  36. <div
  37. :class="[
  38. 'tier-item-cont',
  39. {
  40. 'is-active': curElement.id === element.id
  41. }
  42. ]"
  43. >
  44. {{ element.desc }}
  45. </div>
  46. <!-- <div class="tier-item-cont">{{ element.zindex }}:{{ element.id }}</div> -->
  47. </div>
  48. </div>
  49. </div>
  50. </template>
  51. <script>
  52. import { mapState, mapMutations, mapActions } from "vuex";
  53. export default {
  54. name: "element-tier-edit",
  55. data() {
  56. return {
  57. curColumn: { id: "1", elements: [] },
  58. curDragElement: null,
  59. curDropElementId: null,
  60. dragStartScreenY: null,
  61. isDragDown: false
  62. };
  63. },
  64. computed: {
  65. ...mapState("free", ["curPage", "curElement"])
  66. },
  67. watch: {
  68. curPage: {
  69. immediate: true,
  70. handler(val) {
  71. this.selectColumn(val.columns && val.columns[0]);
  72. }
  73. },
  74. curElement(val) {
  75. if (!val.id) return;
  76. const columnIndex = this.curPage.columns.findIndex(column =>
  77. column.elements.find(elem => elem.id === val.id)
  78. );
  79. if (columnIndex === -1) return;
  80. this.selectColumn(this.curPage.columns[columnIndex]);
  81. }
  82. },
  83. methods: {
  84. ...mapMutations("free", ["setCurElement"]),
  85. ...mapActions("free", ["moveElementToElement"]),
  86. selectColumn(column) {
  87. if (column) {
  88. if (column.id === this.curColumn.id) return;
  89. this.curColumn = column;
  90. } else {
  91. this.curColumn = { id: "1", elements: [] };
  92. }
  93. },
  94. selectElement(element) {
  95. this.setCurElement(element);
  96. },
  97. getRelateElement(dom) {
  98. let element = null;
  99. let parentNode = dom;
  100. while (!element && !parentNode.className.includes("tier-list")) {
  101. if (
  102. !element &&
  103. parentNode["id"] &&
  104. parentNode["id"].includes("tier-element")
  105. ) {
  106. element = parentNode;
  107. } else {
  108. parentNode = parentNode.parentNode;
  109. }
  110. }
  111. return element;
  112. },
  113. getElementId(tierId) {
  114. return tierId.replace("tier-", "");
  115. },
  116. checkElementsIsSiblings(elementId1, elementId2) {
  117. const pos1 = this.curColumn.elements.findIndex(
  118. elem => elem.id === elementId1
  119. );
  120. const pos2 = this.curColumn.elements.findIndex(
  121. elem => elem.id === elementId2
  122. );
  123. return Math.abs(pos1 - pos2) <= 1;
  124. },
  125. getSiblingElement(elementId, offset) {
  126. const pos = this.curColumn.elements.findIndex(
  127. elem => elem.id === elementId
  128. );
  129. return this.curColumn.elements[pos + offset] || null;
  130. },
  131. dragStart(e, element) {
  132. this.dragStartScreenY = e.screenY;
  133. this.curDragElement = element;
  134. },
  135. dragOver(e) {
  136. // console.log(e.target);
  137. this.isDragDown = e.screenY > this.dragStartScreenY;
  138. if (e.target.className.includes("tier-list")) {
  139. const curDropElement = this.isDragDown
  140. ? this.curColumn.elements.slice(-1)[0]
  141. : this.curColumn.elements[0];
  142. this.curDropElementId = curDropElement.id;
  143. return;
  144. }
  145. const elementDom = this.getRelateElement(e.target);
  146. if (!elementDom) return;
  147. const targetId = this.getElementId(elementDom.id);
  148. const curDropElement = this.getSiblingElement(targetId, 0);
  149. this.curDropElementId = curDropElement.id;
  150. },
  151. dropInnerElement() {
  152. // console.log(this.curDragElement.id, this.curDropElementId);
  153. if (this.curDragElement.id === this.curDropElementId) return;
  154. // 往下:target上一个位置
  155. // 往上:target下一个位置
  156. this.moveElementToElement({
  157. curElement: this.curDragElement,
  158. toElementId: this.curDropElementId,
  159. curColumnId: this.curColumn.id,
  160. isDragDown: this.isDragDown
  161. });
  162. },
  163. dragEnd() {
  164. this.curDragElement = null;
  165. this.curDropElementId = null;
  166. this.dragStartScreenY = null;
  167. }
  168. }
  169. };
  170. </script>