ElemExplainEdit.vue 3.8 KB

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