index.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <template>
  2. <ElDialog v-if="isModal" v-model="showSearch" :show-close="false" title="菜单搜索">
  3. <el-select
  4. filterable
  5. :reserve-keyword="false"
  6. remote
  7. placeholder="请输入菜单内容"
  8. :remote-method="remoteMethod"
  9. style="width: 100%"
  10. @change="handleChange"
  11. >
  12. <el-option
  13. v-for="item in options"
  14. :key="item.value"
  15. :label="item.label"
  16. :value="item.value"
  17. />
  18. </el-select>
  19. </ElDialog>
  20. <div v-else class="custom-hover" @click.stop="showTopSearch = !showTopSearch">
  21. <Icon icon="ep:search" />
  22. <el-select
  23. @click.stop
  24. filterable
  25. :reserve-keyword="false"
  26. remote
  27. placeholder="请输入菜单内容"
  28. :remote-method="remoteMethod"
  29. class="overflow-hidden transition-all-600"
  30. :class="showTopSearch ? '!w-220px ml2' : '!w-0'"
  31. @change="handleChange"
  32. >
  33. <el-option
  34. v-for="item in options"
  35. :key="item.value"
  36. :label="item.label"
  37. :value="item.value"
  38. />
  39. </el-select>
  40. </div>
  41. </template>
  42. <script lang="ts" setup>
  43. defineProps({
  44. isModal: {
  45. type: Boolean,
  46. default: true
  47. }
  48. })
  49. const router = useRouter() // 路由对象
  50. const showSearch = ref(false) // 是否显示弹框
  51. const showTopSearch = ref(false) // 是否显示顶部搜索框
  52. const value: Ref = ref('') // 用户输入的值
  53. const routers = router.getRoutes() // 路由对象
  54. const options = computed(() => {
  55. // 提示选项
  56. if (!value.value) {
  57. return []
  58. }
  59. const list = routers.filter((item: any) => {
  60. if (item.meta.title?.indexOf(value.value) > -1 || item.path.indexOf(value.value) > -1) {
  61. return true
  62. }
  63. })
  64. return list.map((item) => {
  65. return {
  66. label: `${item.meta.title}${item.path}`,
  67. value: item.path
  68. }
  69. })
  70. })
  71. function remoteMethod(data) {
  72. // 这里可以执行相应的操作(例如打开搜索框等)
  73. value.value = data
  74. }
  75. function handleChange(path) {
  76. router.push({ path })
  77. hiddenSearch()
  78. hiddenTopSearch()
  79. }
  80. function hiddenSearch() {
  81. showSearch.value = false
  82. }
  83. function hiddenTopSearch() {
  84. showTopSearch.value = false
  85. }
  86. onMounted(() => {
  87. window.addEventListener('keydown', listenKey)
  88. window.addEventListener('click', hiddenTopSearch)
  89. })
  90. onUnmounted(() => {
  91. window.removeEventListener('keydown', listenKey)
  92. window.removeEventListener('click', hiddenTopSearch)
  93. })
  94. // 监听 ctrl + k
  95. function listenKey(event) {
  96. if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
  97. // 阻止触发浏览器默认事件
  98. event.preventDefault()
  99. showSearch.value = !showSearch.value
  100. // 这里可以执行相应的操作(例如打开搜索框等)
  101. }
  102. }
  103. defineExpose({
  104. openSearch: () => {
  105. showSearch.value = true
  106. }
  107. })
  108. </script>