index.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <template>
  2. <div class="app-table">
  3. <table class="app-table__body" cellspacing="0" cellpadding="0">
  4. <thead>
  5. <Draggable class="app-table__row" :list="columns" tag="tr" item-key="key">
  6. <template #header v-if="$slots.expand">
  7. <th class="app-table__cell expand"></th>
  8. </template>
  9. <template #item="{ element }">
  10. <th class="app-table__cell">{{ element.label }}</th>
  11. </template>
  12. </Draggable>
  13. </thead>
  14. <tbody>
  15. <template v-for="(row, i) in dataList" :key="i">
  16. <tr class="app-table__row" @click="rowClick(i)">
  17. <td class="app-table__cell expand" v-if="$slots.expand">
  18. <Icon name="arrow-down" v-if="selectedIndex === i" />
  19. <Icon name="arrow" v-else />
  20. </td>
  21. <td class="app-table__cell" :class="column.className" v-for="(column, n) in columns"
  22. :key="i + n.toString()">
  23. <slot :name="column.prop" :value="row[column.prop]" :row="row">{{ row[column.prop] }}</slot>
  24. </td>
  25. </tr>
  26. <!-- expand -->
  27. <tr class="app-table__row expand" v-show="selectedIndex === i" v-if="$slots.expand">
  28. <td class="app-table__cell" :colspan="columns.length + 1">
  29. <slot name="expandRow" :row="row"></slot>
  30. </td>
  31. </tr>
  32. </template>
  33. </tbody>
  34. </table>
  35. </div>
  36. </template>
  37. <script lang="ts" setup>
  38. import { PropType, ref } from 'vue'
  39. import { Icon } from 'vant'
  40. import { TableColumn } from './types'
  41. import Draggable from 'vuedraggable'
  42. const emit = defineEmits(['rowClick'])
  43. const props = defineProps({
  44. // 数据列表
  45. dataList: {
  46. type: Array,
  47. default: () => ([]),
  48. },
  49. columns: {
  50. type: Array as PropType<TableColumn[]>,
  51. default: () => ([]),
  52. },
  53. })
  54. const selectedIndex = ref(-1);
  55. const rowClick = (index: number) => {
  56. if (selectedIndex.value === index) {
  57. selectedIndex.value = -1;
  58. } else {
  59. selectedIndex.value = index;
  60. }
  61. emit('rowClick', index, props.dataList[index]);
  62. }
  63. </script>
  64. <style lang="less" scoped>
  65. @import './index.less';
  66. </style>