customTable.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <!-- 搜索表单 -->
  2. <template>
  3. <div style="margin-top: 10px">
  4. <el-button type="primary" @click="addColumn" v-if="edit">新增列</el-button>
  5. <el-button type="primary" @click="addRow" v-if="edit">新增行</el-button>
  6. <table style="margin-top: 10px" :id="id">
  7. <thead>
  8. <tr>
  9. <th v-for="(item, index) in columns" class="tableTh">
  10. <i
  11. class="el-icon-delete delete"
  12. style="display: none"
  13. @click="removeColumn(index)"
  14. v-if="edit"
  15. ></i>
  16. <input
  17. v-model="item.value"
  18. type="text"
  19. class="templateInput"
  20. :id="item.id"
  21. :readonly="item.readonly == 2||!edit"
  22. @click="inputClick(item)"
  23. />
  24. </th>
  25. <th v-if="edit"></th>
  26. </tr>
  27. </thead>
  28. <tbody>
  29. <tr v-for="(row, rowIndex) in rows">
  30. <td v-for="item in row.cells"
  31. ><input
  32. v-model="item.value"
  33. type="text"
  34. class="templateInput"
  35. :id="item.id"
  36. :readonly="item.readonly == 2||!edit"
  37. @click="inputClick(item)"
  38. /></td>
  39. <td v-if="edit">
  40. <i
  41. class="sort-handle el-icon-delete delete"
  42. style="color: #f56c6c"
  43. @click="removeRow(rowIndex)"
  44. ></i
  45. ></td>
  46. </tr>
  47. </tbody>
  48. </table>
  49. </div>
  50. </template>
  51. <script>
  52. import dictMixins from '@/mixins/dictMixins';
  53. import { generateRandomString } from '@/utils/util';
  54. export default {
  55. props: {},
  56. mixins: [dictMixins],
  57. props: {
  58. id: '',
  59. edit: {
  60. default: true,
  61. type: Boolean
  62. },
  63. },
  64. data() {
  65. return {
  66. form: null,
  67. valueObj: {},
  68. domId: '',
  69. rightClickShow: false,
  70. columns: [],
  71. rows: []
  72. };
  73. },
  74. methods: {
  75. // 方法:添加新列
  76. addColumn() {
  77. this.columns.push({
  78. value: `列${this.columns.length + 1}`,
  79. id: generateRandomString(5),
  80. readonly: 1
  81. });
  82. this.rows.forEach((row) => {
  83. row.cells.push({
  84. value: '',
  85. readonly: 1,
  86. id: generateRandomString(5)
  87. });
  88. });
  89. },
  90. // 方法:删除指定列
  91. removeColumn(index) {
  92. this.columns.splice(index, 1);
  93. this.rows.forEach((row) => {
  94. row.cells.splice(index, 1);
  95. });
  96. },
  97. // 方法:添加新行
  98. addRow() {
  99. const newRow = {
  100. cells: Array(this.columns.length)
  101. .fill(null)
  102. .map(() => ({
  103. readonly: 1,
  104. value: '',
  105. id: generateRandomString(5)
  106. }))
  107. };
  108. this.rows.push(newRow);
  109. },
  110. // 方法:删除指定行
  111. removeRow(index) {
  112. this.rows.splice(index, 1);
  113. },
  114. objInit() {
  115. if (Object.keys(this.valueObj).length) {
  116. for (let key in this.valueObj) {
  117. this.$nextTick(() => {
  118. let dom = document.getElementById(key);
  119. dom.value = this.valueObj[key];
  120. });
  121. }
  122. }
  123. },
  124. getValue() {
  125. return {
  126. form: null,
  127. valueObj: {
  128. columns: this.columns,
  129. rows: this.rows
  130. }
  131. };
  132. },
  133. init({ form, valueObj }) {
  134. this.form = form;
  135. this.columns = valueObj.columns;
  136. this.rows = valueObj.rows;
  137. },
  138. editInputChange(domObj) {
  139. let columnsIndex = this.columns.findIndex(
  140. (item) => item.id == this.domId
  141. );
  142. if (columnsIndex >= 0) {
  143. this.$set(this.columns, columnsIndex, domObj);
  144. return;
  145. }
  146. this.rows.forEach((item, index) => {
  147. let rowsIndex = item.cells.findIndex(
  148. (cells) => cells.id == this.domId
  149. );
  150. // console.log(rowsIndex,'rowsIndex')
  151. if (rowsIndex >= 0) {
  152. this.$set(this.rows[index].cells, rowsIndex, domObj);
  153. }
  154. });
  155. },
  156. inputClick(item) {
  157. if(!this.edit){
  158. return
  159. }
  160. this.domId = item.id;
  161. this.$emit('editShow', {
  162. templateDivRef: 'customTextRef' + this.id,
  163. domObj: {
  164. isNoWidth: true,
  165. id: item.id,
  166. readonly: item.readonly,
  167. value: item.value
  168. }
  169. });
  170. }
  171. }
  172. };
  173. </script>
  174. <style lang="scss" scoped>
  175. :deep(.templateInput) {
  176. width: 100%;
  177. border: solid 1px #bfbfbf;
  178. padding: 1px;
  179. margin: 1px;
  180. margin-left: 3px;
  181. text-align: center;
  182. background-color: #fff;
  183. }
  184. table {
  185. width: 100%;
  186. border-collapse: collapse;
  187. }
  188. th,
  189. td {
  190. border: 1px solid #ddd;
  191. padding: 0;
  192. text-align: center;
  193. }
  194. th {
  195. background-color: #f2f2f2;
  196. }
  197. tr:nth-child(even) {
  198. background-color: #f9f9f9;
  199. }
  200. input:focus {
  201. border-color: #66afe9; /* 改变边框颜色 */
  202. outline: none; /* 移除默认的轮廓线 */
  203. }
  204. .tableTh:hover {
  205. position: relative;
  206. .delete {
  207. display: block !important;
  208. position: absolute;
  209. right: 0;
  210. top: 0;
  211. color: #f56c6c;
  212. }
  213. }
  214. </style>