ElemCompositionEdit.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <template>
  2. <div class="elem-composition elem-composition-edit">
  3. <div class="elem-title" v-if="data.showTitle" ref="ElemTitle">
  4. {{ data.parent.topicName }}
  5. </div>
  6. <div class="elem-body" :style="bodyStyle">
  7. <div
  8. class="elem-composition-elements"
  9. @drop.prevent="dropInnerElement($event)"
  10. @dragover.prevent
  11. @dragleave.prevent
  12. >
  13. <elem-composition-element-edit
  14. v-for="element in data.elements"
  15. :key="element.id"
  16. :data="element"
  17. :transform-fit="rebuildGuides"
  18. @resize-over="elementResizeOver"
  19. ></elem-composition-element-edit>
  20. <!-- guide-lines -->
  21. <div class="element-guide-lines">
  22. <div
  23. class="guide-line guide-line-x"
  24. v-for="line in xLines"
  25. :key="`x-${line.top}`"
  26. :style="line"
  27. ></div>
  28. <div
  29. class="guide-line guide-line-y"
  30. v-for="line in yLines"
  31. :key="`y-${line.left}`"
  32. :style="line"
  33. ></div>
  34. </div>
  35. </div>
  36. </div>
  37. </div>
  38. </template>
  39. <script>
  40. import { mapState, mapMutations, mapActions } from "vuex";
  41. import ElemCompositionElementEdit from "./ElemCompositionElementEdit";
  42. import guideLinesMixins from "../../mixins/guideLines";
  43. export default {
  44. name: "elem-composition-edit",
  45. components: { ElemCompositionElementEdit },
  46. mixins: [guideLinesMixins],
  47. props: {
  48. data: {
  49. type: Object
  50. }
  51. },
  52. data() {
  53. return {
  54. bodyStyle: {}
  55. };
  56. },
  57. computed: {
  58. ...mapState("card", ["curDragElement"])
  59. },
  60. watch: {
  61. "data.parent": {
  62. handler() {
  63. this.modifyBodyStyle();
  64. }
  65. }
  66. },
  67. mounted() {
  68. this.modifyBodyStyle();
  69. },
  70. methods: {
  71. ...mapMutations("card", ["setCurDragElement", "setCurElement"]),
  72. ...mapActions("card", ["rebuildPages", "modifyElementChild"]),
  73. modifyBodyStyle() {
  74. this.$nextTick(() => {
  75. let height = this.data.h;
  76. if (this.data.showTitle) {
  77. height = this.data.h - this.$refs.ElemTitle.clientHeight;
  78. }
  79. this.bodyStyle = {
  80. height: height + "px"
  81. };
  82. });
  83. },
  84. dropInnerElement(e) {
  85. let { layerX: x, layerY: y } = e;
  86. const { offsetLeft, offsetTop } = this.getOffsetInfo(e.target);
  87. // 作文题的子元素中会新增container字段
  88. const curElement = {
  89. ...this.curDragElement,
  90. x: x + offsetLeft,
  91. y: y + offsetTop,
  92. container: {
  93. id: this.data.id,
  94. type: this.data.type
  95. }
  96. };
  97. if (["LINES", "GRIDS"].includes(curElement.type)) {
  98. curElement.w = this.data.parent.w;
  99. curElement.x = 0;
  100. }
  101. this.elementResizeOver(curElement);
  102. this.setCurDragElement({});
  103. this.setCurElement(curElement);
  104. },
  105. getOffsetInfo(dom, endParent = "elem-composition-elements") {
  106. let parentNode = dom;
  107. let offsetTop = 0,
  108. offsetLeft = 0;
  109. while (!parentNode.className.includes(endParent)) {
  110. offsetTop += parentNode.offsetTop;
  111. offsetLeft += parentNode.offsetLeft;
  112. parentNode = parentNode.offsetParent;
  113. }
  114. return {
  115. offsetLeft,
  116. offsetTop
  117. };
  118. },
  119. elementResizeOver(element) {
  120. this.clear();
  121. this.modifyElementChild(element);
  122. this.$nextTick(() => {
  123. this.rebuildPages();
  124. });
  125. },
  126. rebuildGuides(element, actionType) {
  127. return this.rebuild(this.data.elements, element, actionType);
  128. }
  129. }
  130. };
  131. </script>