group-table.vue 7.0 KB

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