searchSelect.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <template>
  2. <div>
  3. <v-autocomplete
  4. :search-input.sync="searchInput"
  5. full-width
  6. :items="items"
  7. v-model="modelValue"
  8. v-bind="$attrs"
  9. v-on="$listeners"
  10. @change="$emit('update', value)"
  11. >
  12. <template v-slot:append-item>
  13. <div class="d-flex align-center justify-center">
  14. <v-btn v-if="items.length < total" :loading="loading" text color="primary" @click="handleMore">加载更多</v-btn>
  15. <no-more v-else></no-more>
  16. </div>
  17. </template>
  18. </v-autocomplete>
  19. </div>
  20. </template>
  21. <script>
  22. import NoMore from '@/components/NoMore'
  23. import { debounce } from 'lodash'
  24. export default {
  25. name: 'search-select',
  26. components: { NoMore },
  27. props: {
  28. value: {
  29. type: [String, Number, Array],
  30. default: null
  31. },
  32. init: {
  33. type: Function,
  34. default: () => {
  35. return Promise.resolve({ data: [], total: 0 })
  36. }
  37. },
  38. filterSearch: {
  39. type: Function,
  40. default: (val) => {
  41. return val
  42. }
  43. }
  44. },
  45. data () {
  46. return {
  47. modelValue: null,
  48. searchInput: null,
  49. loading: false,
  50. items: [],
  51. total: 0,
  52. pageInfo: {
  53. size: 50,
  54. current: 1
  55. }
  56. }
  57. },
  58. watch: {
  59. value (val) {
  60. this.modelValue = val
  61. },
  62. searchInput: {
  63. handler: debounce(function (val, oldVal) {
  64. this.handleSearch()
  65. }, 500),
  66. immediate: true
  67. }
  68. },
  69. methods: {
  70. // 通过id回显初始化
  71. setInitialize (id) {
  72. this.pageInfo.current = 1
  73. this.init({
  74. id,
  75. pageInfo: this.pageInfo
  76. }).then(({ data, total }) => {
  77. this.items = [...data]
  78. this.total = total
  79. })
  80. },
  81. // 重置
  82. reset () {
  83. this.modelValue = null
  84. this.pageInfo.current = 1
  85. this.init({
  86. searchInput: null,
  87. pageInfo: this.pageInfo
  88. }).then(({ data, total }) => {
  89. this.items = [...data]
  90. this.total = total
  91. })
  92. },
  93. handleSearch () {
  94. this.pageInfo.current = 1
  95. this.init({
  96. searchInput: this.filterSearch(this.searchInput),
  97. pageInfo: this.pageInfo
  98. }).then(({ data, total }) => {
  99. this.items = [...data]
  100. this.total = total
  101. })
  102. },
  103. handleMore () {
  104. this.loading = true
  105. this.pageInfo.current++
  106. this.init({
  107. searchInput: this.filterSearch(this.searchInput),
  108. pageInfo: this.pageInfo
  109. }).then(({ data, total }) => {
  110. this.items.push(...data)
  111. this.total = total
  112. }).finally(() => {
  113. this.loading = false
  114. })
  115. }
  116. }
  117. }
  118. </script>
  119. <style lang="scss" scoped>
  120. </style>