ExtTable.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <style scoped lang="scss">
  2. :deep(.el-table thead th.el-table__cell ) {
  3. background: var(--el-fill-color-light);
  4. }
  5. /**
  6. 未生效 todo
  7. */
  8. :deep(el-table td.el-table__cell div) {
  9. .name-label {
  10. cursor: pointer;
  11. color: var(--el-color-primary-light-1);
  12. }
  13. }
  14. </style>
  15. <template>
  16. <div>
  17. <el-table
  18. :border="border"
  19. :stripe="stripe"
  20. :height="height"
  21. highlight-current-row
  22. current-row-key="id"
  23. row-key="id"
  24. :data="dataList"
  25. v-loading="loading"
  26. @row-dblclick="handleRowDblclick"
  27. @selection-change="handleTableSelectionChange"
  28. @sort-change="handleTableSortChange">
  29. <template #empty>
  30. <el-empty></el-empty>
  31. </template>
  32. <el-table-column type="selection" align="center" width="55" v-if="selectable" fixed="left"/>
  33. <el-table-column
  34. v-for="field in state.cols"
  35. :key="field.prop"
  36. :label="field.label"
  37. :type="field.type"
  38. :column-key="field.prop"
  39. :width="field.width"
  40. :min-width="field.minWidth"
  41. :fixed="field.fixed"
  42. :render-header="field.renderHeader"
  43. :sortable="field.sortable"
  44. :resizable="!field.fixed"
  45. :show-overflow-tooltip="!field.fixed&&field.width>150"
  46. reserve-selection
  47. >
  48. <template #default="{row}">
  49. <!-- {{field.prop}}-->
  50. <!-- {{row}}-->
  51. <!-- {{row[field.prop]}}-->
  52. <template v-if="field.type==='expand'">
  53. <p style="padding-left: 2em;" v-html="row[field.prop]"></p>
  54. </template>
  55. <template v-else>
  56. <template v-if="field.render">
  57. <ExtRender :func="field.render" :data="row"/>
  58. </template>
  59. <template v-else-if="field.type==='rich'">
  60. <p v-html="row[field.prop]"></p>
  61. </template>
  62. <template v-else-if="field.type==='dict'">
  63. <!-- 字典-->
  64. <ExtDLabel v-if="field.conf.dict" :type="field.conf.dict" v-model="row[field.prop]"/>
  65. <ExtDLabel v-else-if="field.conf.range" :data-range="field.conf.range" v-model="row[field.prop]"/>
  66. </template>
  67. <template v-else-if="field.type==='rate'">
  68. <el-rate v-model="row[field.prop]" allow-half/>
  69. </template>
  70. <template v-else-if="field.type==='progress'">
  71. <el-progress type="circle" :percentage="row[field.prop]" :status="{'success':row[field.prop]>=100}"/>
  72. </template>
  73. <template v-else-if="field.type==='dept'||field.type==='user'">
  74. <el-tag v-for="(v,id) in fieldUtil.value(field,row)" :key="id">{{ v }}</el-tag>
  75. </template>
  76. <template v-else-if="field.type==='bool'">
  77. <ext-boolean v-model="row[field.prop]" disabled/>
  78. </template>
  79. <template v-else-if="field.type==='avatar'">
  80. <el-avatar :size="50" :src="u.fmt.fmtImg(row[field.prop])"/>
  81. </template>
  82. <template v-else-if="field.type==='image'">
  83. <ext-upload
  84. v-model="row[field.prop]"
  85. :multiple="field.conf?.multiple"
  86. style="width: 100%"
  87. mime="image"
  88. readonly >
  89. </ext-upload>
  90. </template>
  91. <template v-else-if="field.type==='attach'">
  92. <ext-upload
  93. v-model="row[field.prop]"
  94. :multiple="field.conf?.multiple"
  95. style="width: 100%"
  96. mime="attach"
  97. readonly >
  98. </ext-upload>
  99. </template>
  100. <div v-else>{{ fieldUtil.value(field, row) }}</div>
  101. </template>
  102. </template>
  103. </el-table-column>
  104. <!-- <template v-if="column.slot" v-for="(column,idx) in cls" slot-scope="{row,index}" :slot="column.slot">
  105. <Input :disabled="readonly" class="z-no-border" v-model="row[column.key]"/>
  106. </template>-->
  107. </el-table>
  108. </div>
  109. </template>
  110. <script setup lang="ts" name="ExtTable">
  111. import {reactive, onMounted,defineAsyncComponent} from 'vue';
  112. import fieldUtil from "/@/utils/field";
  113. import ExtDLabel from "/@/components/form/ExtDLabel.vue";
  114. import ExtRender from "/@/components/form/ExtRender.vue";
  115. import ExtBoolean from "/@/components/form/ExtBoolean.vue";
  116. import u from "/@/utils/u";
  117. const ExtUpload = defineAsyncComponent(() => import("/@/components/form/ExtUpload.vue"));
  118. const emit = defineEmits(['on-sort-change', 'on-check-change', 'on-row-dblclick']);
  119. const props = defineProps({
  120. loading: {
  121. type: Boolean,
  122. default: true
  123. },
  124. columns: {
  125. type: Array < IField >,
  126. require: true,
  127. default: () => []
  128. },
  129. dataList: {
  130. type: Array
  131. },
  132. border: {
  133. type: Boolean,
  134. default: true
  135. },
  136. height: {
  137. type: Number,
  138. default: 500
  139. },
  140. stripe: {
  141. type: Boolean,
  142. default: false
  143. },
  144. selectable: {
  145. type: Boolean,
  146. default: false
  147. }
  148. })
  149. const state: any = reactive({
  150. cols: [] as Array<IField>
  151. })
  152. onMounted(() => {
  153. state.cols = fieldUtil.toTableShowField(props.columns);
  154. console.table(state.cols)
  155. })
  156. const handleTableSelectionChange = (selection: any) => {
  157. console.log("handleTableSelectionChange>>", selection)
  158. emit("on-check-change", selection)
  159. }
  160. const handleTableSortChange = (column, prop, order) => {
  161. console.log("handleTableSortChange>>", column, prop, order)
  162. emit("on-sort-change", column)
  163. }
  164. const handleRowDblclick = (row, column, event) => {
  165. emit("on-row-dblclick", row)
  166. }
  167. </script>