ElementTierEdit.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. dragStartPageY: 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. this.$nextTick(() => {
  82. const tierDom = document.getElementById(`tier-${this.curElement.id}`);
  83. this.$refs.TierList.scrollTop = tierDom.offsetTop;
  84. });
  85. },
  86. },
  87. methods: {
  88. ...mapMutations("free", ["setCurElement"]),
  89. ...mapActions("free", ["moveElementToElement"]),
  90. selectColumn(column) {
  91. if (column) {
  92. if (column.id === this.curColumn.id) return;
  93. this.curColumn = column;
  94. } else {
  95. this.curColumn = { id: "1", elements: [] };
  96. }
  97. },
  98. selectElement(element) {
  99. this.setCurElement(element);
  100. },
  101. getRelateElement(dom) {
  102. let element = null;
  103. let parentNode = dom;
  104. while (!element && !parentNode.className.includes("tier-list")) {
  105. if (
  106. !element &&
  107. parentNode["id"] &&
  108. parentNode["id"].includes("tier-element")
  109. ) {
  110. element = parentNode;
  111. } else {
  112. parentNode = parentNode.parentNode;
  113. }
  114. }
  115. return element;
  116. },
  117. getElementId(tierId) {
  118. return tierId.replace("tier-", "");
  119. },
  120. checkElementsIsSiblings(elementId1, elementId2) {
  121. const pos1 = this.curColumn.elements.findIndex(
  122. (elem) => elem.id === elementId1
  123. );
  124. const pos2 = this.curColumn.elements.findIndex(
  125. (elem) => elem.id === elementId2
  126. );
  127. return Math.abs(pos1 - pos2) <= 1;
  128. },
  129. getSiblingElement(elementId, offset) {
  130. const pos = this.curColumn.elements.findIndex(
  131. (elem) => elem.id === elementId
  132. );
  133. return this.curColumn.elements[pos + offset] || null;
  134. },
  135. dragStart(e, element) {
  136. this.dragStartPageY = e.pageY;
  137. this.curDragElement = element;
  138. },
  139. dragOver(e) {
  140. // console.log(e.target);
  141. this.isDragDown = e.pageY > this.dragStartPageY;
  142. if (e.target.className.includes("tier-list")) {
  143. const curDropElement = this.isDragDown
  144. ? this.curColumn.elements.slice(-1)[0]
  145. : this.curColumn.elements[0];
  146. this.curDropElementId = curDropElement.id;
  147. return;
  148. }
  149. const elementDom = this.getRelateElement(e.target);
  150. if (!elementDom) return;
  151. const targetId = this.getElementId(elementDom.id);
  152. const curDropElement = this.getSiblingElement(targetId, 0);
  153. this.curDropElementId = curDropElement.id;
  154. },
  155. dropInnerElement() {
  156. // console.log(this.curDragElement.id, this.curDropElementId);
  157. if (this.curDragElement.id === this.curDropElementId) return;
  158. // 往下:target上一个位置
  159. // 往上:target下一个位置
  160. this.moveElementToElement({
  161. curElement: this.curDragElement,
  162. toElementId: this.curDropElementId,
  163. curColumnId: this.curColumn.id,
  164. isDragDown: this.isDragDown,
  165. });
  166. },
  167. dragEnd() {
  168. this.curDragElement = null;
  169. this.curDropElementId = null;
  170. this.dragStartPageY = null;
  171. },
  172. },
  173. };
  174. </script>