refactor: 优化搜索相关组件和逻辑

1. 重构搜索历史数据结构,从Set改为Array类型
2. 优化MineSurvey组件,限制显示3条问卷项
3. 修复搜索框清空时未重置banner的问题
4. 添加关键词变化时自动触发搜索
5. 优化搜索结果页面的布局和样式
6. 添加useSearch hook文件
This commit is contained in:
Huangzhe
2025-05-19 16:51:23 +08:00
parent 3b0c71989b
commit ee887dadb4
6 changed files with 71 additions and 16 deletions

View File

@@ -0,0 +1,39 @@
import { fetchHistory as fetchHistoryApi } from '@/api/history';
import { hotSearch } from '@/api/home';
import type { HotSearch } from '@/api/types/hotSearch';
import { ref } from 'vue';
// function useFetchKeywordResult(keyword: string) {
// // 历史列表
// const history = ref<Set<string>>(new Set());
// // 从服务器接受的列表内容
// const list = ref<HotSearch[]>([]);
// const { data } = await hotSearch();
// list.value = data.data;
// return { list };
// }
// 初始化历史
function fetchHistory() {
const history = ref<string[]>([]);
// 屏蔽从storage获取记录的方式
// const historyStr = localStorage.getItem('history')
// if (historyStr) {
// history.value = new Set(JSON.parse(historyStr))
// } else {
// history.value = new Set()
// }
fetchHistoryApi().then(({ data }) => {
data.data.forEach((item: { id: number; keyword: string }) => {
history.value.push(item.keyword);
});
});
return { history };
}
export { fetchHistory };

View File

@@ -60,6 +60,9 @@ async function updateKeyword(key?: string) {
// 排除边界条件
if (!keyword.value) {
// 清空字符内容,重新获取历史,关闭 loading 状态
keyword.value = '';
banners.value = [];
initialHistory()
loading.value = false;
return;
@@ -87,7 +90,7 @@ function updatePageCount(value: number) {
watch(keyword, async () => {
dirty.value = true;
// 重新获取数据
// await handleSearch();
await handleSearch();
});
// 索引变动之后,立刻进行搜索 (没有进行防抖)

View File

@@ -6,12 +6,11 @@ import { handleSearch, keyword, loading } from '@/views/HomeSearch/Hooks/useSurv
import Layout from '@/components/Layout/CommonLayout.vue';
import { visible } from '@/views/HomeSearch/Hooks/useHomeSearch';
import RecommendTag from '@/views/HomeSearch/components/Recommend/Index.vue';
import { onMounted } from 'vue';
import { onMounted, type Ref } from 'vue';
import ImageSlider from '../Home/components/ImageSlider/Index.vue';
import { banners } from '@/views/HomeSearch/Hooks/useSurveySearch';
// 确保 keyword 是字符串类型,提供默认值
const searchKeyword = keyword.value || '';
const searchKeyword = keyword as Ref<string>;
onMounted(() => {
// 当页面取消挂载时,重置页面展示的状态
@@ -25,7 +24,7 @@ onMounted(() => {
<search :focus="true" v-model:value="searchKeyword" :search="handleSearch" />
</div>
<!-- 广告区域 -->
<image-slider :banners="banners" v-if="banners?.length" />
<image-slider :banners="banners" v-if="banners?.length > 0 && keyword" />
<section class="result" v-if="loading">
<!-- 我的任务区域 -->

View File

@@ -1,7 +1,13 @@
<script setup lang="ts">
import { index, surveys, lastIndex, keyword } from '@/views/HomeSearch/Hooks/useSurveySearch';
import {
index,
surveys as _surveys,
lastIndex,
keyword
} from '@/views/HomeSearch/Hooks/useSurveySearch';
import SurveyItem from '@/components/SurveyItem/Index.vue';
import { useRouter } from 'vue-router';
import { computed } from 'vue';
const router = useRouter();
/**
@@ -21,23 +27,27 @@ function handleSurveyClick(survey: { sn: any }) {
}
});
}
const surveys = computed(() => {
// 取前三个元素
return _surveys.value.slice(0, 3);
});
</script>
<template>
<van-list class="list-container" :offset="10" :finished="lastIndex" @load="handleLoadStatus">
<div class="list-container">
<van-cell v-for="survey in surveys" :key="survey" class="list-item">
<template #extra>
<survey-item :survey="survey" @click="handleSurveyClick(survey)" />
</template>
</van-cell>
</van-list>
</div>
</template>
<style scoped lang="scss">
@use '@/assets/css/theme';
.list-container {
max-height: 30vh;
// max-height: 30vh;
overflow: scroll;
.list-item {

View File

@@ -1,10 +1,13 @@
<script setup lang="ts">
import { fetchHistory } from '@/hooks/request/useSearch';
import Layout from '@/components/Layout/CommonLayout.vue';
import { list, useFetchRecommon, history, delHistory } from './hooks/useRecommend';
import { list, useFetchRecommon, delHistory } from './hooks/useRecommend';
import { Delete } from '@element-plus/icons-vue';
import { handleSearch } from '../../Hooks/useSurveySearch';
useFetchRecommon();
const { history } = fetchHistory();
</script>
<template>
@@ -21,8 +24,9 @@ useFetchRecommon();
:hit="false"
round
v-for="tag in list"
>{{ tag.key_word }}</el-tag
>
{{ tag.key_word }}
</el-tag>
</el-space>
</layout>
@@ -35,9 +39,9 @@ useFetchRecommon();
</div>
</section>
</template>
<el-space>
<section style="display: flex; flex-wrap: wrap">
<el-tag
style="color: black"
style="color: black; margin: 3px"
color="white"
:hit="false"
round
@@ -45,7 +49,7 @@ useFetchRecommon();
v-for="tag in history"
>{{ tag }}</el-tag
>
</el-space>
</section>
</layout>
</section>
</template>

View File

@@ -6,7 +6,7 @@ import { ref } from 'vue';
// 从服务器接受的列表内容
const list = ref<HotSearch[]>([]);
// 历史列表
const history = ref<Set<string>>(new Set());
const history = ref<string[]>([]);
initialHistory();
async function useFetchRecommon() {
@@ -28,7 +28,7 @@ async function initialHistory() {
console.log(data);
data.data.forEach((item: { id: number; keyword: string }) => {
history.value.add(item.keyword);
history.value.push(item.keyword);
});
}