group-table.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <template>
  2. <el-table class="custom-table" :show-summary="summary" :class="customClass" stripe :data="data.data" :height="height" style="width: 100%" @cell-click="onClick" @header-click="onHeaderClick" ref="groupTable">
  3. <template v-for="(col, cIndex) in data.column" :key="col">
  4. <el-table-column v-if="col.child && col.child.length > 0" :label="col.name" :key="col">
  5. <el-table-column
  6. v-for="(sub, sindex) in col.child"
  7. :key="sub"
  8. :index="cIndex"
  9. :class-name="getClassName(cIndex, sindex)"
  10. :label="sub.name"
  11. :prop="sub.field"
  12. :width="sub.width"
  13. :sortable="sub.sortable"
  14. :show-overflow-tooltip="!sub.slot"
  15. :fixed="sub.fixed"
  16. :align="sub.align ? sub.align : 'center'"
  17. :resizable="sub.resizable"
  18. :header-align="'center'"
  19. >
  20. <template v-if="sub.slot == true" #default="item">
  21. <slot :name="sub.field" :column="sub" :row="item.row" :all="item" :data="item.row[item.field]"></slot>
  22. </template>
  23. </el-table-column>
  24. </el-table-column>
  25. <el-table-column
  26. v-if="!col.child"
  27. :label="col.name"
  28. :prop="col.field"
  29. :width="col.width"
  30. :sortable="col.sortable"
  31. :show-overflow-tooltip="!col.slot"
  32. :fixed="col.fixed"
  33. :align="col.align ? col.align : 'center'"
  34. :resizable="col.resizable"
  35. :header-align="'center'"
  36. >
  37. <template v-if="col.slot == true" #default="item">
  38. <slot :name="col.field" :column="col" :row="item.row" :all="item" :data="item.row[col.field]"></slot>
  39. </template>
  40. </el-table-column>
  41. </template>
  42. </el-table>
  43. <el-pagination class="mg-t-8"
  44. v-if="pageable" @current-change="handleCurrentChange"
  45. :current-page="currentPage" :page-size="pageSize" :total="data.total" v-bind="elPaggingProps">
  46. </el-pagination>
  47. </template>
  48. <script>
  49. export default {
  50. // 名称
  51. name: "ComTable",
  52. // 使用组件
  53. components: {},
  54. // 传入参数
  55. props: {
  56. /**
  57. * {
  58. column: [{
  59. name: "风机名称",
  60. child:[{
  61. field: "name",
  62. width:'', // 宽度
  63. click:function(){} // 点击事件
  64. sortable:fasle,
  65. slot:false,
  66. fixed:false,
  67. align:'center',
  68. resizable :false,
  69. }]
  70. }],
  71. total:200
  72. }
  73. */
  74. data: Object,
  75. height: {
  76. type: String,
  77. default: "",
  78. },
  79. pageSize: {
  80. type: Number,
  81. default: 0,
  82. },
  83. customClass: {
  84. type: String,
  85. default: "",
  86. },
  87. elPaggingProps: {
  88. type: Object,
  89. default: () => {
  90. return {
  91. layout: "total, sizes, prev, pager, next, jumper",
  92. // "page-sizes": [100, 200, 300, 400],
  93. };
  94. },
  95. },
  96. isColumnLight: {
  97. type: Boolean,
  98. default: true,
  99. },
  100. summary: {
  101. type: Boolean,
  102. default: false,
  103. },
  104. },
  105. emits: {
  106. onPagging: null,
  107. headerClick: null,
  108. },
  109. // 数据
  110. data() {
  111. return {
  112. currentPage: 1,
  113. headerIndex: -1,
  114. subIndex: -1,
  115. };
  116. },
  117. computed: {
  118. tableData() {
  119. let that = this;
  120. if (this.sortCol == "") {
  121. return this.data.data;
  122. } else {
  123. let data = this.data.data;
  124. data.sort((a, b) => {
  125. let rev = 1;
  126. if (that.sortType == "ASC") rev = 1;
  127. else if (that.sortType == "DESC") rev = -1;
  128. if (a[that.sortCol] > b[that.sortCol]) return rev * 1;
  129. if (a[that.sortCol] < b[that.sortCol]) return rev * -1;
  130. return 0;
  131. });
  132. return data;
  133. }
  134. },
  135. pageable() {
  136. return this.pageSize != 0;
  137. },
  138. pages() {
  139. if (this.pageable) return parseInt(this.data.total / this.pageSize) + 1;
  140. else return 0;
  141. },
  142. startRow() {
  143. if (this.pageable) return (this.currentPage - 1) * this.pageSize;
  144. else return 0;
  145. },
  146. endRow() {
  147. if (this.pageable) return this.currentPage * this.pageSize;
  148. else return this.data.data.length;
  149. },
  150. },
  151. // 函数
  152. methods: {
  153. onClick(row, column, cell, event) {
  154. if (column.rawColumnKey.click) column.rawColumnKey.click(event, row);
  155. },
  156. onHeaderClick(column, event) {
  157. if (column.level == 2) {
  158. this.headerIndex = column.index;
  159. this.subIndex = column.no;
  160. }
  161. this.$emit("headerClick", { level: column.level, event: event, col: column.rawColumnKey, data: this.data.data });
  162. },
  163. handleCurrentChange(val) {
  164. this.currentPage = val;
  165. this.$emit("onPagging", {
  166. pageIndex: this.currentPage,
  167. pageSize: this.pageSize,
  168. start: this.startRow,
  169. end: this.endRow,
  170. });
  171. },
  172. getClassName(cindex, sindex) {
  173. if (this.isColumnLight == true && cindex == this.headerIndex && sindex == this.subIndex) return "light";
  174. return "";
  175. },
  176. },
  177. // 生命周期钩子
  178. beforeCreate() {
  179. // 创建前
  180. },
  181. created() {
  182. // 创建后
  183. },
  184. beforeMount() {
  185. // 渲染前
  186. },
  187. mounted() {
  188. // 渲染后
  189. },
  190. beforeUpdate() {},
  191. updated() {},
  192. };
  193. </script>
  194. <style lang="less">
  195. @titleGray: #9ca5a8;
  196. @rowGray: #606769;
  197. @darkBack: #536268;
  198. .com-table {
  199. width: 100%;
  200. border-collapse: collapse;
  201. thead {
  202. tr {
  203. display: table;
  204. table-layout: fixed;
  205. width: 100%;
  206. th {
  207. background-color: fade(@darkBack, 20%);
  208. height: 30px;
  209. line-height: 30px;
  210. color: @titleGray;
  211. font-weight: 400;
  212. font-size: @fontsize-s;
  213. position: sticky;
  214. top: 0;
  215. cursor: pointer;
  216. &.light,
  217. &.always-light {
  218. color: @green;
  219. }
  220. }
  221. }
  222. }
  223. tbody {
  224. display: block;
  225. tr {
  226. display: table;
  227. table-layout: fixed;
  228. width: 100%;
  229. &:nth-child(2n) {
  230. background-color: fade(@rowGray, 20%);
  231. }
  232. td {
  233. padding: 0.556vh 0;
  234. color: @rowGray;
  235. text-align: center;
  236. font-size: @fontsize-s;
  237. white-space: nowrap;
  238. overflow: hidden;
  239. text-overflow: ellipsis;
  240. &.light,
  241. &.always-light {
  242. color: @green !important;
  243. }
  244. &.num {
  245. font-family: "Bicubik";
  246. font-weight: 400;
  247. }
  248. }
  249. }
  250. }
  251. .el-pagination {
  252. color: @gray;
  253. .el-pagination__total {
  254. color: @gray;
  255. }
  256. button {
  257. &.btn-next,
  258. &.btn-prev {
  259. background: center center no-repeat fade(@gray, 20);
  260. color: @gray-l;
  261. }
  262. &:disabled {
  263. color: @gray-l;
  264. background-color: fade(@gray, 20);
  265. cursor: not-allowed;
  266. }
  267. }
  268. .el-pager li {
  269. color: @gray-l;
  270. background: fade(@gray, 20);
  271. &.active {
  272. color: @green;
  273. }
  274. }
  275. .el-input__inner {
  276. color: @gray-l;
  277. background: fade(@gray, 20);
  278. border: 1px solid fade(@gray, 20);
  279. }
  280. }
  281. }
  282. </style>