SearchList.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <template>
  2. <a-card id="search-result" :header-style="{ backgroundColor: ' #7786BC', borderRadius: '10px 10px 0 0' }">
  3. <template #title>
  4. <div class="title">搜索结果</div>
  5. </template>
  6. <template #extra>
  7. <div class="title">共{{ total <= 9999 ? total : '9999+' }}条</div>
  8. </template>
  9. <!-- -->
  10. <a-list
  11. style="width: 100%"
  12. :max-height="scroll_height"
  13. :bordered="false"
  14. :scrollbar="scrollbar"
  15. @reach-bottom="toLoadMore"
  16. >
  17. <template #scroll-loading>
  18. <div v-if="bottom">无更多数据了</div>
  19. <a-spin v-else />
  20. </template>
  21. <a-list-item
  22. :class="current_id === item.id ? 'item-active' : ''"
  23. style="cursor: pointer"
  24. v-for="item in search_list"
  25. :key="item.id"
  26. @click="checkDetail(item)"
  27. >
  28. <div v-html="item.content" class="clamped-text"></div>
  29. </a-list-item>
  30. </a-list>
  31. <a-spin class="loading" v-if="is_loading" />
  32. </a-card>
  33. </template>
  34. <script setup>
  35. import { ref, computed, onMounted } from 'vue';
  36. const props = defineProps({
  37. list: {
  38. type: Array,
  39. default: () => []
  40. },
  41. total: {
  42. type: Number,
  43. default: 0
  44. },
  45. current: {
  46. type: Number,
  47. default: 1
  48. },
  49. pageSize: {
  50. type: Number,
  51. default: 10
  52. },
  53. set_loading: {
  54. type: Boolean,
  55. default: false
  56. }
  57. });
  58. const emit = defineEmits(['checkDetail']);
  59. const search_list = computed(() => {
  60. return props.list;
  61. });
  62. const is_loading = computed(() => {
  63. return props.setLoading;
  64. });
  65. const bottom = ref(false);
  66. const scrollbar = ref(true);
  67. const scroll_height = ref('calc(100vh - 220px)');
  68. const current_id = ref('');
  69. const toLoadMore = () => {
  70. if (props.current * props.pageSize >= props.total) {
  71. bottom.value = true;
  72. return;
  73. }
  74. // 去加载第二页数据
  75. bottom.value = false;
  76. emit('loadMore');
  77. };
  78. // 查看详情
  79. const checkDetail = (item) => {
  80. current_id.value = item.id;
  81. emit('checkDetail', item);
  82. };
  83. onMounted(() => {
  84. window.addEventListener('resize', () => {
  85. const height = document.getElementById('search-result').offsetHeight;
  86. scroll_height.value = height + 'px';
  87. });
  88. });
  89. </script>
  90. <style scoped lang="css">
  91. .arco-card {
  92. height: 100%;
  93. border-radius: 10px 10px 0 0;
  94. }
  95. .arco-list-item:hover {
  96. background: rgba(61, 104, 225, 0.8);
  97. color: #fff;
  98. }
  99. .item-active {
  100. background: #3d68e1;
  101. color: #fff;
  102. }
  103. .title {
  104. color: #fff;
  105. }
  106. .clamped-text {
  107. display: -webkit-box;
  108. -webkit-line-clamp: 2;
  109. -webkit-box-orient: vertical;
  110. overflow: hidden;
  111. text-overflow: ellipsis;
  112. line-height: 1.5;
  113. max-height: 3em;
  114. }
  115. :deep(.search-result-high) {
  116. color: #f00;
  117. }
  118. :deep(.arco-card-body) {
  119. padding: 0 !important;
  120. }
  121. .loading {
  122. position: absolute;
  123. top: 50%;
  124. left: 50%;
  125. transform: translate(-50%, -50%);
  126. }
  127. </style>