index.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <script lang="ts" setup>
  2. import { useSettingsStore } from '@/store/modules/settings'
  3. import { getList } from '@/api/search'
  4. const vFocus: any = {
  5. mounted(el: HTMLElement) {
  6. el.querySelector('input')?.focus()
  7. },
  8. }
  9. const settingsStore = useSettingsStore()
  10. const { theme } = storeToRefs(settingsStore)
  11. let timer: any = null
  12. const state = reactive({
  13. dialogVisible: false,
  14. queryForm: {
  15. searchWord: '',
  16. },
  17. restaurants: [],
  18. })
  19. const loadAll = async () => {
  20. const {
  21. data: { list },
  22. } = await getList()
  23. state.restaurants = list
  24. }
  25. onMounted(() => {
  26. if (theme.value.showSearch) loadAll()
  27. })
  28. const openDialog = () => {
  29. state.queryForm.searchWord = ''
  30. state.dialogVisible = true
  31. }
  32. const querySearchAsync = (queryString: any, cb: any) => {
  33. const restaurants = state.restaurants
  34. const results = queryString
  35. ? restaurants.filter(createFilter(queryString))
  36. : restaurants
  37. clearTimeout(timer)
  38. timer = setTimeout(() => {
  39. cb(results)
  40. }, 500)
  41. }
  42. const createFilter = (queryString: string) => (state: any) =>
  43. state.value.includes(queryString.toLowerCase())
  44. const handleSelect = (item: any) => {
  45. if (item.url) {
  46. window.open(item.url)
  47. } else {
  48. window.open(`https://www.baidu.com/s?wd=${item.value}`)
  49. }
  50. }
  51. </script>
  52. <template>
  53. <span v-if="theme.showSearch">
  54. <vab-icon icon="search-line" @click="openDialog" />
  55. <el-dialog v-model="state.dialogVisible" :width="'40%'">
  56. <el-autocomplete
  57. v-model="state.queryForm.searchWord"
  58. v-focus
  59. :fetch-suggestions="querySearchAsync"
  60. select-when-unmatched
  61. @select="handleSelect"
  62. >
  63. <template #prefix><vab-icon icon="search-line" /></template>
  64. </el-autocomplete>
  65. </el-dialog>
  66. </span>
  67. </template>
  68. <style lang="scss" scoped>
  69. :deep() {
  70. .el-dialog {
  71. &__header {
  72. display: none;
  73. border: 0 !important;
  74. }
  75. &__body {
  76. padding: 0;
  77. border: 0 !important;
  78. }
  79. &__footer {
  80. display: none;
  81. }
  82. }
  83. .el-autocomplete {
  84. width: 100%;
  85. transition: none;
  86. .el-input__inner {
  87. width: 100%;
  88. height: 60px;
  89. padding-left: $base-padding;
  90. line-height: 60px;
  91. }
  92. }
  93. }
  94. </style>