Spaces:
Sleeping
Sleeping
| <template> | |
| <div class="pc-search"> | |
| <!-- 搜索区域 --> | |
| <div class="pc-search__input"> | |
| <el-input | |
| v-model="keyword" | |
| placeholder="请输入搜索关键词或输入链接直接解析" | |
| clearable | |
| @keyup.enter="handleSearch" | |
| > | |
| <template #prefix> | |
| <el-icon><Search /></el-icon> | |
| </template> | |
| <template #suffix> | |
| <el-icon v-if="keyword" class="search-icon" @click="handleSearch"> | |
| <ArrowRight /> | |
| </el-icon> | |
| </template> | |
| </el-input> | |
| </div> | |
| <!-- 用户操作区 --> | |
| <div class="pc-search__actions"> | |
| <el-tooltip effect="dark" content="退出登录" placement="bottom"> | |
| <el-button class="logout-btn" type="text" @click="handleLogout"> | |
| <el-icon><SwitchButton /></el-icon> | |
| </el-button> | |
| </el-tooltip> | |
| </div> | |
| </div> | |
| </template> | |
| <script setup lang="ts"> | |
| import { ref, computed, watch } from "vue"; | |
| import { useResourceStore } from "@/stores/resource"; | |
| import { useRoute, useRouter } from "vue-router"; | |
| import { ElMessage } from "element-plus"; | |
| import { Search, ArrowRight, SwitchButton } from "@element-plus/icons-vue"; | |
| import { STORAGE_KEYS } from "@/constants/storage"; | |
| // 路由相关 | |
| const route = useRoute(); | |
| const router = useRouter(); | |
| const resourcStore = useResourceStore(); | |
| // 响应式数据 | |
| const keyword = ref(""); | |
| const routeKeyword = computed(() => route.query.keyword as string); | |
| // 退出登录 | |
| const handleLogout = () => { | |
| localStorage.removeItem(STORAGE_KEYS.TOKEN); | |
| router.push("/login"); | |
| ElMessage.success("已退出登录"); | |
| }; | |
| // 搜索处理 | |
| const handleSearch = async () => { | |
| const searchText = keyword.value.trim(); | |
| if (!searchText) { | |
| ElMessage.warning("请输入搜索内容"); | |
| return; | |
| } | |
| // 链接解析处理 | |
| if (searchText.startsWith("http")) { | |
| await resourcStore.parsingCloudLink(searchText); | |
| return; | |
| } | |
| // 关键词搜索 | |
| await resourcStore.searchResources(searchText); | |
| if (route.path !== "/resource") { | |
| router.push("/resource"); | |
| } | |
| }; | |
| // 监听路由参数变化 | |
| watch( | |
| () => routeKeyword.value, | |
| (newKeyword) => { | |
| if (newKeyword) { | |
| keyword.value = newKeyword; | |
| handleSearch(); | |
| } else { | |
| keyword.value = resourcStore.keyword; | |
| } | |
| } | |
| ); | |
| watch( | |
| () => resourcStore.keyword, | |
| (newKeyword) => { | |
| keyword.value = newKeyword; | |
| } | |
| ); | |
| </script> | |
| <style lang="scss" scoped> | |
| @import "@/styles/common.scss"; | |
| .pc-search { | |
| @include flex-center; | |
| justify-content: space-between; | |
| gap: 16px; | |
| width: 100%; | |
| // 搜索输入区域 | |
| &__input { | |
| flex: 1; | |
| min-width: 0; // 防止溢出 | |
| :deep(.el-input) { | |
| --el-input-height: 44px; | |
| .el-input__wrapper { | |
| @include glass-effect; | |
| padding: 0 16px; | |
| border-radius: var(--theme-radius); | |
| box-shadow: | |
| inset 0 0 0 1px rgba(255, 255, 255, 0.1), | |
| 0 2px 4px rgba(0, 0, 0, 0.05), | |
| 0 1px 2px rgba(0, 0, 0, 0.1); | |
| border: 1px solid rgba(0, 0, 0, 0.08); | |
| transition: var(--theme-transition); | |
| background: rgba(255, 255, 255, 0.9); | |
| &:hover { | |
| border-color: var(--theme-primary); | |
| box-shadow: | |
| inset 0 0 0 1px var(--theme-primary), | |
| 0 4px 8px rgba(0, 0, 0, 0.1); | |
| } | |
| &.is-focus { | |
| border-color: var(--theme-primary); | |
| box-shadow: | |
| inset 0 0 0 1px var(--theme-primary), | |
| 0 4px 8px rgba(0, 0, 0, 0.1), | |
| 0 0 0 3px rgba(0, 102, 204, 0.1); | |
| background: #fff; | |
| } | |
| } | |
| .el-input__inner { | |
| font-size: 15px; | |
| color: var(--theme-text-primary); | |
| height: 42px; | |
| line-height: 42px; | |
| &::placeholder { | |
| color: var(--theme-text-secondary); | |
| } | |
| } | |
| .el-input__prefix-inner { | |
| .el-icon { | |
| font-size: 18px; | |
| color: var(--theme-text-secondary); | |
| margin-right: 8px; | |
| } | |
| } | |
| .search-icon { | |
| font-size: 18px; | |
| cursor: pointer; | |
| color: var(--theme-primary); | |
| transition: var(--theme-transition); | |
| margin-left: 8px; | |
| &:hover { | |
| transform: scale(1.1); | |
| } | |
| } | |
| } | |
| } | |
| // 操作区域 | |
| &__actions { | |
| .logout-btn { | |
| @include glass-effect; | |
| width: 44px; | |
| height: 44px; | |
| padding: 0; | |
| border-radius: var(--theme-radius); | |
| transition: var(--theme-transition); | |
| .el-icon { | |
| font-size: 20px; | |
| color: var(--theme-text-regular); | |
| transition: var(--theme-transition); | |
| } | |
| &:hover { | |
| background: var(--theme-primary); | |
| transform: translateY(-2px); | |
| box-shadow: var(--theme-shadow-sm); | |
| .el-icon { | |
| color: #fff; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| </style> | |