p-table.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <template>
  2. <div>
  3. <div style="width: 30%; margin: 15px auto">
  4. <el-input readonly v-model="dataBody.table.tabName"></el-input>
  5. </div>
  6. <table class="dataBody-box">
  7. <tbody>
  8. <tr v-for="(item, index) in dataBody.rows" :key="index">
  9. <td
  10. @contextmenu="showMenu(index, zindex)"
  11. class="cell"
  12. v-for="(row, zindex) in item"
  13. :key="zindex"
  14. :rowspan="row.rowSpan"
  15. :colspan="row.colSpan"
  16. v-show="row.displayFlag == '0'"
  17. >
  18. <div v-show="false">
  19. {{ (dataBody.rows[index][zindex].colNum = zindex) }}
  20. {{ (dataBody.rows[index][zindex].rowNum = index) }}
  21. </div>
  22. <el-input
  23. class="table-input"
  24. v-model="row.cellVal"
  25. :readonly="!isUpdate"
  26. ></el-input>
  27. </td>
  28. </tr>
  29. </tbody>
  30. </table>
  31. <vue-context-menu
  32. v-if="isUpdate"
  33. :contextMenuData="contextMenuData"
  34. @deleteHang="deleteHang"
  35. @addHangUp="addHangUp"
  36. ></vue-context-menu>
  37. </div>
  38. </template>
  39. <script>
  40. export default {
  41. props: {
  42. //table数据源
  43. dataBody: {
  44. required: true,
  45. type: Object,
  46. },
  47. isUpdate: {
  48. required: false,
  49. type: Boolean,
  50. default: false,
  51. },
  52. },
  53. data() {
  54. return {
  55. contextMenuData: {
  56. menuName: "demo",
  57. //菜单显示的位置
  58. axis: {
  59. x: null,
  60. y: null,
  61. },
  62. //菜单选项
  63. menulists: [
  64. {
  65. fnHandler: "deleteHang", //绑定事件
  66. btnName: "删除行", //菜单名称
  67. },
  68. {
  69. fnHandler: "addHangUp", //绑定事件
  70. btnName: "插入行", //菜单名称
  71. },
  72. ],
  73. },
  74. hangIndex: "", // 行索引
  75. lieIndex: "", // 列索引
  76. };
  77. },
  78. methods: {
  79. showMenu(index, zindex) {
  80. this.hangIndex = index;
  81. this.lieIndex = zindex;
  82. event.preventDefault();
  83. var x = event.clientX;
  84. var y = event.clientY;
  85. console.log(x, y);
  86. // Get the current location
  87. this.contextMenuData.axis = {
  88. x,
  89. y,
  90. };
  91. },
  92. // 向上增加行
  93. addHangUp() {
  94. let itemArr = [];
  95. for (let i = 0; i < this.hangIndex; i++) {
  96. this.dataBody.rows[i].map((item) => {
  97. if (
  98. this.hangIndex <= parseInt(item.rowSpan) + i - 1 &&
  99. parseInt(item.rowSpan) > 1
  100. ) {
  101. item.rowSpan = parseInt(item.rowSpan) + 1;
  102. }
  103. });
  104. }
  105. itemArr = JSON.parse(JSON.stringify(this.dataBody.rows[this.hangIndex]));
  106. itemArr.map((item) => {
  107. item.rowSpan = "1";
  108. item.cellVal = "";
  109. });
  110. this.dataBody.rows.splice(this.hangIndex, 0, itemArr);
  111. },
  112. // 删除行
  113. deleteHang() {
  114. if (
  115. parseInt(this.dataBody.rows[this.hangIndex][this.lieIndex].rowSpan) > 1
  116. ) {
  117. this.$message({
  118. message: "当前行有合并项不能删除",
  119. type: "wanrning",
  120. });
  121. return;
  122. }
  123. let num = 0;
  124. this.dataBody.rows[this.hangIndex].map((item, index) => {
  125. if (parseInt(item.rowSpan) > 1) {
  126. this.dataBody.rows[parseInt(this.hangIndex) + 1][index].displayFlag =
  127. "0";
  128. this.dataBody.rows[parseInt(this.hangIndex) + 1][index].rowSpan =
  129. parseInt(item.rowSpan) - 1;
  130. } else if (item.displayFlag == "1") {
  131. for (let i = this.hangIndex; i >= 0; i--) {
  132. num = 0;
  133. this.dataBody.rows[i].map((item, zindex) => {
  134. if (item.displayFlag == "0") {
  135. num++;
  136. }
  137. if (
  138. parseInt(item.rowSpan) > 1 &&
  139. zindex == index &&
  140. this.hangIndex <= parseInt(item.rowSpan) + i - 1
  141. ) {
  142. item.rowSpan = parseInt(item.rowSpan) - 1;
  143. }
  144. });
  145. if (num == this.dataBody.rows[i].length) {
  146. return;
  147. }
  148. }
  149. }
  150. });
  151. this.dataBody.rows.splice(this.hangIndex, 1);
  152. },
  153. },
  154. watch: {
  155. dataBody(val, oldval) {
  156. console.log(val);
  157. console.log(oldval);
  158. },
  159. },
  160. };
  161. </script>
  162. <style lang="scss" scoped>
  163. .dataBody-box {
  164. border-collapse: collapse;
  165. }
  166. .dataBody-box {
  167. td,
  168. th {
  169. border: 1px solid black;
  170. }
  171. }
  172. </style>