data-table.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <template>
  2. <div id="data-table">
  3. <el-table
  4. ref="table"
  5. row-key="id"
  6. :data="data"
  7. border
  8. stripe
  9. size="small"
  10. :max-height="height !== null ? height : ''"
  11. @select="handleSelectionChange"
  12. @select-all="handleSelectAll"
  13. >
  14. <el-table-column type="selection" width="55" v-if="select" prop="id" :reserve-selection="true"> </el-table-column>
  15. <template v-for="(item, index) in fields">
  16. <template v-if="item.custom">
  17. <el-table-column :key="index" align="center" :label="item.label" v-bind="item.options">
  18. <template v-slot="{ row, $index }">
  19. <slot name="custom" v-bind="{ item, row, $index }"></slot>
  20. </template>
  21. </el-table-column>
  22. </template>
  23. <template v-else>
  24. <el-table-column :key="index" align="center" :label="item.label" :prop="item.prop" :formatter="toFormatter" sortable v-bind="item.options">
  25. </el-table-column>
  26. </template>
  27. </template>
  28. <template v-if="opera.length > 0">
  29. <el-table-column label="操作" align="center">
  30. <template v-slot="{ row, $index }">
  31. <template v-for="(item, index) in opera">
  32. <template v-if="display(item, row)">
  33. <template v-if="item.icon">
  34. <el-tooltip :key="index" effect="dark" :content="item.label" placement="bottom">
  35. <!-- <el-button
  36. :key="index"
  37. type="text"
  38. :icon="item.icon || ''"
  39. size="mini"
  40. @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)"
  41. ></el-button> -->
  42. <el-link
  43. :key="index"
  44. :type="item.type || 'primary'"
  45. :icon="item.icon || ''"
  46. size="mini"
  47. style="padding-right:10px"
  48. :underline="false"
  49. @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)"
  50. >
  51. </el-link>
  52. </el-tooltip>
  53. </template>
  54. <template v-else>
  55. <el-link
  56. :key="index"
  57. :type="item.type || 'primary'"
  58. :icon="item.icon || ''"
  59. size="mini"
  60. style="padding-right:10px"
  61. :underline="false"
  62. @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)"
  63. >
  64. {{ item.label }}
  65. </el-link>
  66. <!-- <el-button :key="index" type="text" size="mini" @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)">
  67. {{ item.label }}
  68. </el-button> -->
  69. </template>
  70. </template>
  71. </template>
  72. </template>
  73. </el-table-column>
  74. </template>
  75. </el-table>
  76. </div>
  77. </template>
  78. <script>
  79. import _ from 'lodash';
  80. export default {
  81. name: 'data-table',
  82. props: {
  83. fields: { type: Array, required: true },
  84. data: { type: Array, required: true },
  85. opera: { type: Array, default: () => [] },
  86. toFormat: null,
  87. height: null,
  88. select: { type: Boolean, default: false },
  89. selected: { type: Array, default: () => [] },
  90. },
  91. components: {},
  92. data: () => ({
  93. pageSelected: [],
  94. selectFirst: true,
  95. }),
  96. created() {},
  97. computed: {},
  98. methods: {
  99. toFormatter(row, column, cellValue, index) {
  100. let this_fields = this.fields.filter(fil => fil.prop === column.property);
  101. if (this_fields.length > 0) {
  102. let format = _.get(this_fields[0], `format`, false);
  103. if (format) {
  104. let res;
  105. if (_.isFunction(format)) {
  106. res = format(cellValue);
  107. } else {
  108. res = this.toFormat({
  109. model: this_fields[0].prop,
  110. value: cellValue,
  111. });
  112. }
  113. return res;
  114. } else return cellValue;
  115. }
  116. },
  117. handleOpera(data, method, confirm = false, methodZh, label, index) {
  118. if (!method) return;
  119. let self = true;
  120. if (_.isFunction(methodZh)) {
  121. methodZh = methodZh(data);
  122. } else if (!_.isString(methodZh)) {
  123. methodZh = label;
  124. self = false;
  125. }
  126. if (confirm) {
  127. this.$confirm(self ? methodZh : `您确认${methodZh}该数据?`, '提示', {
  128. confirmButtonText: '确定',
  129. cancelButtonText: '取消',
  130. type: 'warning',
  131. })
  132. .then(() => {
  133. this.$emit(method, { data, index });
  134. })
  135. .catch(() => {});
  136. } else {
  137. this.$emit(method, { data, index });
  138. }
  139. },
  140. handleSelectionChange(selection, row) {
  141. // console.log(selection);
  142. // console.log(row);
  143. //根据row是否再pageSelected中,判断是添加还是删除
  144. let res = [];
  145. if (this.pageSelected.find(i => i.id === row.id)) {
  146. res = this.pageSelected.filter(f => f.id !== row.id);
  147. } else {
  148. this.pageSelected.push(row);
  149. res = this.pageSelected;
  150. }
  151. this.$set(this, `pageSelected`, res);
  152. this.$emit(`handleSelect`, _.uniqBy(res, 'id'));
  153. },
  154. handleSelectAll(selection) {
  155. //处于没全选状态,选择之后一定是全选,只有处于全选状态时,才会反选(全取消)
  156. // console.log(selection);
  157. let res = [];
  158. if (selection.length > 0) {
  159. //全选
  160. res = _.uniqBy(this.pageSelected.concat(selection), 'id');
  161. } else {
  162. //全取消
  163. res = _.differenceBy(this.pageSelected, this.data, 'id');
  164. }
  165. this.$set(this, `pageSelected`, res);
  166. this.$emit(`handleSelect`, res);
  167. },
  168. initSelection() {
  169. this.$nextTick(() => {
  170. this.$refs.table.clearSelection();
  171. this.selected.forEach(info => {
  172. let d = this.data.filter(p => p.id === info.id);
  173. if (d.length > 0) this.$refs.table.toggleRowSelection(d[0]);
  174. });
  175. });
  176. },
  177. selectReset() {
  178. this.$refs.table.clearSelection();
  179. },
  180. display(item, row) {
  181. let display = _.get(item, `display`, true);
  182. if (display === true) return true;
  183. else {
  184. let res = display(row);
  185. return res;
  186. }
  187. },
  188. },
  189. watch: {
  190. selected: {
  191. handler(val) {
  192. if (val.length > 0) {
  193. this.pageSelected = val;
  194. this.initSelection();
  195. }
  196. },
  197. immediate: true,
  198. },
  199. data: {
  200. handler(val, oval) {
  201. if (this.select) {
  202. this.initSelection();
  203. }
  204. },
  205. },
  206. },
  207. };
  208. </script>
  209. <style lang="less" scoped></style>