refactor: 重构搜索页
All checks were successful
deploy to server / build-and-deploy (push) Successful in 2m56s
All checks were successful
deploy to server / build-and-deploy (push) Successful in 2m56s
- 提取页面部分为SearchHeader与SearchTabs组件
This commit is contained in:
@ -1,80 +1,10 @@
|
||||
<template>
|
||||
<div class="search-page">
|
||||
<div class="search-header">
|
||||
<h1 class="page-title">{{ $t('search.title') }}</h1>
|
||||
<div class="search-bar">
|
||||
<el-input
|
||||
v-model="keyword"
|
||||
class="search-input"
|
||||
:placeholder="$t('search-placeholder')"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
@keyup.enter="navigateToQuery(keyword)"
|
||||
@clear="handleClear"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="search-button"
|
||||
@click="navigateToQuery(keyword)"
|
||||
>
|
||||
{{ $t('search.search-button') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<search-header v-model="keyword" />
|
||||
<div v-if="loading" class="search-state">
|
||||
<el-skeleton :rows="4" animated />
|
||||
</div>
|
||||
<div v-else-if="hasResults" class="search-results">
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tab-pane :label="`全部(${resultCount['all']})`" name="all">
|
||||
<search-results
|
||||
v-model:current-page="currentPage"
|
||||
:search-items="searchItems"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
:label="`产品(${resultCount['product'] || 0})`"
|
||||
name="product"
|
||||
>
|
||||
<search-results
|
||||
v-model:current-page="currentPage"
|
||||
:search-items="searchItems"
|
||||
category="product"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
:label="`解决方案(${resultCount['solution'] || 0})`"
|
||||
name="solution"
|
||||
>
|
||||
<search-results
|
||||
v-model:current-page="currentPage"
|
||||
:search-items="searchItems"
|
||||
category="solution"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
:label="`相关问题(${resultCount['question'] || 0})`"
|
||||
name="question"
|
||||
>
|
||||
<search-results
|
||||
v-model:current-page="currentPage"
|
||||
:search-items="searchItems"
|
||||
category="question"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
:label="`文档资料(${resultCount['document'] || 0})`"
|
||||
name="document"
|
||||
>
|
||||
<search-results
|
||||
v-model:current-page="currentPage"
|
||||
:search-items="searchItems"
|
||||
category="document"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<search-tabs v-else-if="hasResults" :search-items="searchItems" />
|
||||
<div v-else class="search-state">
|
||||
<el-empty
|
||||
:description="
|
||||
@ -88,8 +18,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Search } from '@element-plus/icons-vue';
|
||||
|
||||
// i18n相关
|
||||
const { t } = useI18n();
|
||||
const { getDirectusLocale } = useLocalizations();
|
||||
@ -97,8 +25,6 @@
|
||||
|
||||
// 路由相关
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const localePath = useLocalePath();
|
||||
|
||||
// 搜索相关
|
||||
const { search } = useMeilisearch();
|
||||
@ -144,44 +70,10 @@
|
||||
})
|
||||
);
|
||||
|
||||
console.log(searchItems.value);
|
||||
|
||||
// 分类控制
|
||||
const activeTab = ref('all');
|
||||
const resultCount = computed(() => {
|
||||
const map: Record<string, number> = { all: searchItems.value.length };
|
||||
for (const item of searchItems.value) {
|
||||
map[item.type] = (map[item.type] ?? 0) + 1;
|
||||
}
|
||||
return map;
|
||||
});
|
||||
|
||||
// 分页控制
|
||||
const currentPage = ref(1);
|
||||
|
||||
const hasResults = computed(() =>
|
||||
filteredSections.value.some((section) => section.hits.length > 0)
|
||||
);
|
||||
|
||||
const navigateToQuery = (value: string) => {
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) return;
|
||||
navigateTo({
|
||||
path: localePath('/search'),
|
||||
query: { query: trimmed },
|
||||
});
|
||||
};
|
||||
|
||||
const handleClear = () => {
|
||||
keyword.value = '';
|
||||
sections.value = [];
|
||||
router.replace(localePath({ path: '/search' }));
|
||||
};
|
||||
|
||||
watch(activeTab, () => {
|
||||
currentPage.value = 1; // 重置页码
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.query.query,
|
||||
async (newQuery) => {
|
||||
@ -216,42 +108,6 @@
|
||||
min-height: 70vh;
|
||||
}
|
||||
|
||||
.search-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 2.25rem;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.search-button {
|
||||
height: 50px;
|
||||
width: 100px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.search-meta {
|
||||
font-size: 0.9rem;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.search-state {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
Reference in New Issue
Block a user