list-helper-evo.vue 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <script setup lang="ts" generic="T extends AnyObject">
  2. import { UnwrapRef } from 'vue'
  3. const props = withDefaults(
  4. defineProps<{
  5. request?: (query: Partial<T>) => Promise<IResData<T[]>>
  6. items?: T[]
  7. query?: Partial<T>
  8. automatic?: boolean
  9. mockList?: Partial<T>[]
  10. contentClass?: string
  11. }>(),
  12. {
  13. automatic: true,
  14. query: () => ({}),
  15. contentClass: 'flex flex-col',
  16. },
  17. )
  18. const slot = defineSlots<{
  19. default(props: { item: UnwrapRef<T>; index: number; isLast: boolean }): any
  20. }>()
  21. const request = computed(() => {
  22. if (props.request) {
  23. return props.request
  24. } else {
  25. return async () => {
  26. return { code: 0, msg: '', data: props.items }
  27. }
  28. }
  29. })
  30. const { data, run: setData } = useRequest(() => request.value({ ...props.query }), {
  31. immediate: false,
  32. })
  33. onMounted(async () => {
  34. if (props.mockList) {
  35. data.value = props.mockList as T[]
  36. return
  37. }
  38. if (props.automatic) {
  39. await setData()
  40. }
  41. })
  42. watch(
  43. () => props.query,
  44. async () => {
  45. if (props.mockList) {
  46. data.value = props.mockList as T[]
  47. return
  48. }
  49. await setData()
  50. },
  51. )
  52. defineExpose({
  53. reload: async () => {
  54. await setData()
  55. },
  56. })
  57. </script>
  58. <template>
  59. <div class="flex-grow relative flex flex-col">
  60. <div :class="contentClass">
  61. <template v-for="(it, index) in data" :key="index">
  62. <slot
  63. :item="it as UnwrapRef<T>"
  64. :index="index"
  65. :isLast="index == (data?.length ?? 0) - 1"
  66. ></slot>
  67. </template>
  68. </div>
  69. <div
  70. v-if="mockList"
  71. class="construction-dashed absolute top-0 right-0 left-0 bottom-0 bg-red/20 flex items-center justify-center pointer-events-none"
  72. >
  73. <div class="text-16 text-black/30">Debug</div>
  74. </div>
  75. </div>
  76. </template>
  77. <style scoped lang="scss">
  78. //@layer utilities {
  79. .construction-dashed {
  80. @apply border-4 border-black/50 border-dashed; /* 基础虚线样式 */
  81. animation: dashed-move 2s linear infinite; /* 虚线移动动画 */
  82. }
  83. //}
  84. @keyframes dashed-move {
  85. from {
  86. border-spacing: 0;
  87. }
  88. to {
  89. border-spacing: 10px;
  90. }
  91. }
  92. </style>