lite-grid.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <el-table
  3. border
  4. style="width: 100%;overflow: auto;"
  5. :size="options.size || 'mini'"
  6. v-bind="options"
  7. :data="data"
  8. :highlight-current-row="currentRow"
  9. @selection-change="selectionChange"
  10. @row-dblclick="dblclick"
  11. @current-change="handleCurrentChange"
  12. >
  13. <el-table-column v-if="selection" type="selection" width="55"></el-table-column>
  14. <slot name="pre"> </slot>
  15. <slot>
  16. <el-table-column
  17. v-for="(item, index) in listFields"
  18. :key="'field' + index"
  19. :label="item.label"
  20. :prop="item.name"
  21. :formatter="item.formatter"
  22. v-bind="item.options"
  23. show-overflow-tooltip
  24. />
  25. </slot>
  26. <slot name="ext"> </slot>
  27. <slot name="oper">
  28. <el-table-column label="操作" :width="options.operWidth || '100'" v-if="!readonly">
  29. <template v-slot:header>
  30. <slot name="oper_header">
  31. <span>操作</span>
  32. </slot>
  33. </template>
  34. <template v-slot="{ row, $index }">
  35. <el-button
  36. v-for="(item, index) in operItems"
  37. :key="'field' + index"
  38. @click="handleOper(item, row, $index, $event)"
  39. type="text"
  40. :size="options.size || 'mini'"
  41. @focus="handleFocus($event)"
  42. >
  43. <el-tooltip v-if="item.icon" :content="item.label"><i :class="item.icon"></i></el-tooltip>
  44. <span v-else>{{ item.label }}</span>
  45. </el-button>
  46. </template>
  47. </el-table-column>
  48. </slot>
  49. <slot name="post"> </slot>
  50. </el-table>
  51. </template>
  52. <script>
  53. import _ from 'lodash';
  54. import { FieldMeta, Operation, Formatter, MergeFilters } from './meta-util';
  55. export default {
  56. name: 'lite-grid',
  57. props: {
  58. currentRow: Boolean, // 是否显示单行高亮
  59. meta: { type: Array, required: true },
  60. readonly: Boolean /* 是否显示操作列 */,
  61. selection: Boolean /* 是否显示多选 */,
  62. options: {
  63. type: Object,
  64. default: () => ({ size: 'mini' }),
  65. } /* 表格扩展属性 */,
  66. operation: {
  67. default: () => [
  68. ['edit', '编辑', 'el-icon-edit'],
  69. ['delete', '删除', 'el-icon-delete', true],
  70. ],
  71. } /* 操作类型 */,
  72. data: Array,
  73. },
  74. methods: {
  75. async handleOper({ event, label, confirm }, data, index, e) {
  76. if (e && e.target) {
  77. e.target.blur();
  78. }
  79. try {
  80. if (confirm) {
  81. const msg = _.isString(confirm) ? confirm : `是否${label}此数据?`;
  82. await this.$confirm(msg, '请确认', {
  83. confirmButtonText: '确定',
  84. cancelButtonText: '取消',
  85. closeOnClickModal: false,
  86. type: 'warning',
  87. });
  88. }
  89. this.$emit(event, data, index);
  90. this.$emit('oper', { event, data, index });
  91. } catch (err) {
  92. if (err == 'cancel') {
  93. this.$message({
  94. type: 'info',
  95. message: `已取消${label}`,
  96. });
  97. }
  98. }
  99. },
  100. selectionChange(selection) {
  101. this.$emit('selection', selection);
  102. },
  103. dblclick(row) {
  104. this.$emit('dblclick', row);
  105. },
  106. handleCurrentChange(val) {
  107. this.$emit('currentRow', val);
  108. },
  109. },
  110. computed: {
  111. listFields() {
  112. const res = this.meta
  113. .map(FieldMeta)
  114. .filter(p => p.slots.list)
  115. .sort((a, b) => a.order - b.order || a.index - b.index)
  116. .map(p => ({
  117. ...p.field,
  118. formatter: Formatter(p, this),
  119. options: MergeFilters(p, this),
  120. }));
  121. // console.log('listFields: ', res);
  122. return res;
  123. },
  124. operItems() {
  125. return Operation(this.operation);
  126. },
  127. },
  128. };
  129. </script>
  130. <style lang="less" scoped>
  131. // .el-table {
  132. // height: 80vh;
  133. // border: none;
  134. // overflow: auto;
  135. // }
  136. .el-table::before {
  137. height: 0;
  138. }
  139. .el-button + .el-button {
  140. margin-left: 5px;
  141. }
  142. </style>