index.vue 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <template>
  2. <el-tree-select
  3. v-if="theme.showSearch"
  4. v-model="searchValue"
  5. class="vab-search"
  6. clearable
  7. :data="addFieldToTree(routes)"
  8. default-expand-all
  9. filterable
  10. highlight-current
  11. :prefix-icon="Search"
  12. @node-click="handleSelect"
  13. >
  14. <template #default="{ data }">
  15. <vab-icon v-if="data.meta && data.meta.icon" :icon="data.meta.icon" />
  16. <span style="margin-left: 3px">{{ translate(data.meta.title) }}</span>
  17. </template>
  18. </el-tree-select>
  19. </template>
  20. <script lang="ts" setup>
  21. import { Search } from '@element-plus/icons-vue'
  22. import { isHashRouterMode } from '/@/config'
  23. import { translate } from '/@/i18n'
  24. import { useRoutesStore } from '/@/store/modules/routes'
  25. import { useSettingsStore } from '/@/store/modules/settings'
  26. import { isExternal } from '/@/utils/validate'
  27. defineOptions({
  28. name: 'VabSearch',
  29. })
  30. const settingsStore = useSettingsStore()
  31. const { theme } = storeToRefs(settingsStore)
  32. const searchValue = ref<any>('')
  33. const router = useRouter()
  34. const route = useRoute()
  35. const routesStore = useRoutesStore()
  36. const { getRoutes: routes } = storeToRefs(routesStore)
  37. const addFieldToTree = (routes: any) => {
  38. routes.forEach((node: any) => {
  39. node.value = node.name
  40. node.label = translate(node.meta.title)
  41. if (node.children && node.children.length > 0) addFieldToTree(node.children)
  42. })
  43. return routes
  44. }
  45. const handleSelect = (item: any) => {
  46. nextTick(() => {
  47. if (!item.children)
  48. if (isExternal(item.path)) {
  49. window.open(item.path)
  50. router.push('/redirect')
  51. return
  52. } else if (item.meta.target === '_blank') {
  53. isHashRouterMode ? window.open(`#${item.path}`) : window.open(item.path)
  54. router.push('/redirect')
  55. return
  56. } else router.push(item.path)
  57. })
  58. }
  59. watch(
  60. route,
  61. () => {
  62. if (route.fullPath.includes('?')) {
  63. //处理query传参
  64. const matched = route.fullPath.match(/\?(.*)$/)
  65. const name: any = route.name
  66. if (matched) name.includes('?') ? (searchValue.value = route.name) : (searchValue.value = `${route.name as string}?${matched[1]}`)
  67. // 详情页显示搜索项
  68. if (route.meta.hidden && name.includes('Detail')) searchValue.value = ''
  69. } else searchValue.value = route.name
  70. },
  71. {
  72. immediate: true,
  73. }
  74. )
  75. </script>
  76. <style lang="scss" scoped>
  77. .vab-search {
  78. :deep() {
  79. .el-input {
  80. width: 150px !important;
  81. }
  82. }
  83. }
  84. </style>