search.vue 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <template>
  2. <div class="q-pa-md relative">
  3. <q-input
  4. v-model="query"
  5. dense
  6. dark
  7. standout
  8. :input-class="inputClass"
  9. @focus="focused = true"
  10. @blur="focused = false"
  11. >
  12. <template v-slot:append>
  13. <q-icon v-if="query === ''" name="search" :class="{ 'text-primary': focused }" />
  14. <q-icon v-else name="clear" class="cursor-pointer" @click="query = ''" :class="{ 'text-primary': focused }" />
  15. </template>
  16. </q-input>
  17. <q-list class="bg-primary shadow-lg rounded mt-5 w-64 absolute text-white z-50 max-h-[200px] overflow-y-auto">
  18. <q-item clickable v-for="result in results" :key="result.item.title" @click="goTo(result.item.url)">
  19. <q-item-section>
  20. <q-item-label>{{ result.item.title }}</q-item-label>
  21. </q-item-section>
  22. </q-item>
  23. </q-list>
  24. </div>
  25. </template>
  26. <script>
  27. export default {
  28. data() {
  29. return {
  30. query: "",
  31. focused: false,
  32. results: [],
  33. searchData: [],
  34. fuse: null,
  35. };
  36. },
  37. watch: {
  38. query() {
  39. this.search();
  40. },
  41. },
  42. computed: {
  43. inputClass() {
  44. return this.focused ? "text-primary" : "";
  45. },
  46. },
  47. async created() {
  48. let response = await fetch("/static/search_index.json");
  49. if (!response.ok) {
  50. throw new Error(`HTTP error! status: ${response.status}`);
  51. }
  52. this.searchData = await response.json();
  53. let options = {
  54. keys: [
  55. { name: "title", weight: 0.7 },
  56. { name: "content", weight: 0.3 },
  57. ],
  58. tokenize: true, // each word is ranked individually
  59. threshold: 0.3,
  60. location: 0,
  61. distance: 10000,
  62. };
  63. this.fuse = new Fuse(this.searchData, options);
  64. },
  65. methods: {
  66. search() {
  67. this.results = this.fuse.search(this.query);
  68. },
  69. goTo(url) {
  70. if (url.startsWith("http")) {
  71. window.open(url, "_blank");
  72. } else {
  73. window.location.href = url;
  74. }
  75. this.query = "";
  76. },
  77. },
  78. };
  79. </script>