AutocompleteWithAPI.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <template>
  2. <main>
  3. <v-autocomplete
  4. v-model="model"
  5. :value="data"
  6. :items="items"
  7. :loading="isLoading"
  8. :search-input.sync="search"
  9. hide-no-data
  10. hide-selected
  11. item-text="textDisplay"
  12. :item-value="itemValue"
  13. :label="$t(label_field)"
  14. :placeholder="$t('start_your_research')"
  15. prepend-icon="mdi-magnify"
  16. :return-object="returnObject"
  17. />
  18. </main>
  19. </template>
  20. <script lang="ts">
  21. import { defineComponent, computed, watch, ref, useContext, onUnmounted, Ref } from '@nuxtjs/composition-api'
  22. import * as _ from 'lodash'
  23. import { QUERY_TYPE } from '~/types/enums'
  24. export default defineComponent({
  25. props: {
  26. label: {
  27. type: String,
  28. required: false
  29. },
  30. field: {
  31. type: String,
  32. required: false
  33. },
  34. data: {
  35. type: String,
  36. required: false
  37. },
  38. readOnly: {
  39. type: Boolean,
  40. required: false
  41. },
  42. itemValue: {
  43. type: String,
  44. default: 'id'
  45. },
  46. itemText: {
  47. type: Array,
  48. required: true
  49. },
  50. returnObject: {
  51. type: Boolean,
  52. default: false
  53. }
  54. },
  55. setup (props) {
  56. const { $dataProvider } = useContext()
  57. const search:Ref<string|null> = ref(null)
  58. const model = ref(null)
  59. const count = ref(0)
  60. const entries = ref([])
  61. const isLoading = ref(false)
  62. const items = computed(() => {
  63. return entries.value.map((entry) => {
  64. const textDisplay:Array<string> = []
  65. for (const text of props.itemText) {
  66. textDisplay.push(entry[text as string])
  67. }
  68. return Object.assign({}, entry, { textDisplay: textDisplay.join(' ') })
  69. })
  70. })
  71. const unwatch = watch(search, _.debounce(async (research) => {
  72. // Items have already been requested
  73. if (isLoading.value) { return }
  74. isLoading.value = true
  75. const response = await $dataProvider.invoke({
  76. type: QUERY_TYPE.DEFAULT,
  77. url: `gps-coordinate-searching?city=${research}`
  78. })
  79. count.value = response.length
  80. entries.value = response
  81. isLoading.value = false
  82. }, 500))
  83. onUnmounted(() => {
  84. unwatch()
  85. })
  86. return {
  87. label_field: props.label ?? props.field,
  88. count,
  89. isLoading,
  90. items,
  91. search,
  92. model
  93. }
  94. }
  95. })
  96. </script>
  97. <style scoped>
  98. </style>