ExtTable.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. <ext-render
  58. class="z-w150"
  59. :data="row[field.prop]"
  60. :render-func="field.render"/>
  61. </template>
  62. <template v-else-if="field.type==='rich'">
  63. <p v-html="row[field.prop]"></p>
  64. </template>
  65. <template v-else-if="field.type==='dict'">
  66. <!-- 字典-->
  67. <ExtDLabel v-if="field.conf.dict" :type="field.conf.dict" v-model="row[field.prop]"/>
  68. <ExtDLabel v-else-if="field.conf.range" :data-range="field.conf.range" v-model="row[field.prop]"/>
  69. </template>
  70. <template v-else-if="field.type==='rate'">
  71. <el-rate v-model="row[field.prop]" allow-half/>
  72. </template>
  73. <template v-else-if="field.type==='progress'">
  74. <el-progress type="circle" :percentage="row[field.prop]" :status="{'success':row[field.prop]>=100}"/>
  75. </template>
  76. <template v-else-if="field.type==='dept'||field.type==='user'">
  77. <el-tag v-for="(v,id) in fieldUtil.value(field,row)" :key="id">{{ v }}</el-tag>
  78. </template>
  79. <template v-else-if="field.type==='bool'">
  80. <ext-boolean v-model="row[field.prop]" disabled/>
  81. </template>
  82. <template v-else-if="field.type==='avatar'">
  83. <el-avatar :size="50" :src="u.fmt.fmtImg(row[field.prop])"/>
  84. </template>
  85. <template v-else-if="field.type==='image'">
  86. <ext-upload
  87. v-model="row[field.prop]"
  88. :multiple="field.conf?.multiple"
  89. style="width: 100%"
  90. mime="image"
  91. readonly >
  92. </ext-upload>
  93. </template>
  94. <template v-else-if="field.type==='attach'">
  95. <ext-upload
  96. v-model="row[field.prop]"
  97. :multiple="field.conf?.multiple"
  98. style="width: 100%"
  99. mime="attach"
  100. readonly >
  101. </ext-upload>
  102. </template>
  103. <div v-else>{{ fieldUtil.value(field, row) }}</div>
  104. </template>
  105. </template>
  106. </el-table-column>
  107. <!-- <template v-if="column.slot" v-for="(column,idx) in cls" slot-scope="{row,index}" :slot="column.slot">
  108. <Input :disabled="readonly" class="z-no-border" v-model="row[column.key]"/>
  109. </template>-->
  110. </el-table>
  111. </div>
  112. </template>
  113. <script setup lang="ts" name="ExtTable">
  114. import {reactive, onMounted,defineAsyncComponent} from 'vue';
  115. import fieldUtil from "/@/utils/field";
  116. import ExtDLabel from "/@/components/form/ExtDLabel.vue";
  117. import ExtBoolean from "/@/components/form/ExtBoolean.vue";
  118. import ExtRender from "/@/components/form/ExtRender.vue";
  119. import u from "/@/utils/u";
  120. const ExtUpload = defineAsyncComponent(() => import("/@/components/form/ExtUpload.vue"));
  121. const emit = defineEmits(['on-sort-change', 'on-check-change', 'on-row-dblclick']);
  122. const props = defineProps({
  123. loading: {
  124. type: Boolean,
  125. default: true
  126. },
  127. columns: {
  128. type: Array < IField >,
  129. require: true,
  130. default: () => []
  131. },
  132. dataList: {
  133. type: Array
  134. },
  135. border: {
  136. type: Boolean,
  137. default: true
  138. },
  139. height: {
  140. type: Number,
  141. default: 500
  142. },
  143. stripe: {
  144. type: Boolean,
  145. default: false
  146. },
  147. selectable: {
  148. type: Boolean,
  149. default: false
  150. }
  151. })
  152. const state: any = reactive({
  153. cols: [] as Array<IField>
  154. })
  155. onMounted(() => {
  156. state.cols = fieldUtil.toTableShowField(props.columns);
  157. //console.table(state.cols)
  158. })
  159. const handleTableSelectionChange = (selection: any) => {
  160. //console.log("handleTableSelectionChange>>", selection)
  161. emit("on-check-change", selection)
  162. }
  163. const handleTableSortChange = (column, prop, order) => {
  164. //console.log("handleTableSortChange>>", column, prop, order)
  165. emit("on-sort-change", column)
  166. }
  167. const handleRowDblclick = (row, column, event) => {
  168. emit("on-row-dblclick", row)
  169. }
  170. </script>