list-helper-evo.vue 2.2 KB

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