From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/components/RouterSearch/index.vue |  121 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 121 insertions(+), 0 deletions(-)

diff --git a/src/components/RouterSearch/index.vue b/src/components/RouterSearch/index.vue
new file mode 100644
index 0000000..52425ec
--- /dev/null
+++ b/src/components/RouterSearch/index.vue
@@ -0,0 +1,121 @@
+<template>
+  <ElDialog v-if="isModal" v-model="showSearch" :show-close="false" title="鑿滃崟鎼滅储">
+    <el-select
+      filterable
+      :reserve-keyword="false"
+      remote
+      placeholder="璇疯緭鍏ヨ彍鍗曞唴瀹�"
+      :remote-method="remoteMethod"
+      style="width: 100%"
+      @change="handleChange"
+    >
+      <el-option
+        v-for="item in options"
+        :key="item.value"
+        :label="item.label"
+        :value="item.value"
+      />
+    </el-select>
+  </ElDialog>
+  <div v-else class="custom-hover" @click.stop="showTopSearch = !showTopSearch">
+    <Icon icon="ep:search" :color="color"/>
+    <el-select
+      @click.stop
+      filterable
+      :reserve-keyword="false"
+      remote
+      placeholder="璇疯緭鍏ヨ彍鍗曞唴瀹�"
+      :remote-method="remoteMethod"
+      class="overflow-hidden transition-all-600"
+      :class="showTopSearch ? '!w-220px ml2' : '!w-0'"
+      @change="handleChange"
+    >
+      <el-option
+        v-for="item in options"
+        :key="item.value"
+        :label="item.label"
+        :value="item.value"
+      />
+    </el-select>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { propTypes } from '@/utils/propTypes'
+defineProps({
+  isModal: {
+    type: Boolean,
+    default: true
+  },
+  color: propTypes.string.def('')
+})
+
+const router = useRouter() // 璺敱瀵硅薄
+const showSearch = ref(false) // 鏄惁鏄剧ず寮规
+const showTopSearch = ref(false) // 鏄惁鏄剧ず椤堕儴鎼滅储妗�
+const value: Ref = ref('') // 鐢ㄦ埛杈撳叆鐨勫��
+
+const routers = router.getRoutes() // 璺敱瀵硅薄
+const options = computed(() => {
+  // 鎻愮ず閫夐」
+  if (!value.value) {
+    return []
+  }
+  const list = routers.filter((item: any) => {
+    if (item.meta.title?.indexOf(value.value) > -1 || item.path.indexOf(value.value) > -1) {
+      return true
+    }
+  })
+  return list.map((item) => {
+    return {
+      label: `${item.meta.title}${item.path}`,
+      value: item.path
+    }
+  })
+})
+
+function remoteMethod(data) {
+  // 杩欓噷鍙互鎵ц鐩稿簲鐨勬搷浣滐紙渚嬪鎵撳紑鎼滅储妗嗙瓑锛�
+  value.value = data
+}
+
+function handleChange(path) {
+  router.push({ path })
+  hiddenSearch()
+  hiddenTopSearch()
+}
+
+function hiddenSearch() {
+  showSearch.value = false
+}
+
+function hiddenTopSearch() {
+  showTopSearch.value = false
+}
+
+onMounted(() => {
+  window.addEventListener('keydown', listenKey)
+  window.addEventListener('click', hiddenTopSearch)
+})
+
+onUnmounted(() => {
+  window.removeEventListener('keydown', listenKey)
+  window.removeEventListener('click', hiddenTopSearch)
+})
+
+// 鐩戝惉 ctrl + k
+function listenKey(event) {
+  if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
+    // 闃绘瑙﹀彂娴忚鍣ㄩ粯璁や簨浠�
+    event.preventDefault()
+    showSearch.value = !showSearch.value
+    // 杩欓噷鍙互鎵ц鐩稿簲鐨勬搷浣滐紙渚嬪鎵撳紑鎼滅储妗嗙瓑锛�
+  }
+}
+
+defineExpose({
+  openSearch: () => {
+    showSearch.value = true
+  }
+})
+</script>

--
Gitblit v1.8.0