refactor: 优化搜索相关组件和逻辑
1. 重构搜索历史数据结构,从Set改为Array类型 2. 优化MineSurvey组件,限制显示3条问卷项 3. 修复搜索框清空时未重置banner的问题 4. 添加关键词变化时自动触发搜索 5. 优化搜索结果页面的布局和样式 6. 添加useSearch hook文件
This commit is contained in:
39
src/hooks/request/useSearch.ts
Normal file
39
src/hooks/request/useSearch.ts
Normal 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 };
|
||||||
@@ -60,6 +60,9 @@ async function updateKeyword(key?: string) {
|
|||||||
|
|
||||||
// 排除边界条件
|
// 排除边界条件
|
||||||
if (!keyword.value) {
|
if (!keyword.value) {
|
||||||
|
// 清空字符内容,重新获取历史,关闭 loading 状态
|
||||||
|
keyword.value = '';
|
||||||
|
banners.value = [];
|
||||||
initialHistory()
|
initialHistory()
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
return;
|
return;
|
||||||
@@ -87,7 +90,7 @@ function updatePageCount(value: number) {
|
|||||||
watch(keyword, async () => {
|
watch(keyword, async () => {
|
||||||
dirty.value = true;
|
dirty.value = true;
|
||||||
// 重新获取数据
|
// 重新获取数据
|
||||||
// await handleSearch();
|
await handleSearch();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 索引变动之后,立刻进行搜索 (没有进行防抖)
|
// 索引变动之后,立刻进行搜索 (没有进行防抖)
|
||||||
|
|||||||
@@ -6,12 +6,11 @@ import { handleSearch, keyword, loading } from '@/views/HomeSearch/Hooks/useSurv
|
|||||||
import Layout from '@/components/Layout/CommonLayout.vue';
|
import Layout from '@/components/Layout/CommonLayout.vue';
|
||||||
import { visible } from '@/views/HomeSearch/Hooks/useHomeSearch';
|
import { visible } from '@/views/HomeSearch/Hooks/useHomeSearch';
|
||||||
import RecommendTag from '@/views/HomeSearch/components/Recommend/Index.vue';
|
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 ImageSlider from '../Home/components/ImageSlider/Index.vue';
|
||||||
import { banners } from '@/views/HomeSearch/Hooks/useSurveySearch';
|
import { banners } from '@/views/HomeSearch/Hooks/useSurveySearch';
|
||||||
|
|
||||||
// 确保 keyword 是字符串类型,提供默认值
|
const searchKeyword = keyword as Ref<string>;
|
||||||
const searchKeyword = keyword.value || '';
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 当页面取消挂载时,重置页面展示的状态
|
// 当页面取消挂载时,重置页面展示的状态
|
||||||
@@ -25,7 +24,7 @@ onMounted(() => {
|
|||||||
<search :focus="true" v-model:value="searchKeyword" :search="handleSearch" />
|
<search :focus="true" v-model:value="searchKeyword" :search="handleSearch" />
|
||||||
</div>
|
</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">
|
<section class="result" v-if="loading">
|
||||||
<!-- 我的任务区域 -->
|
<!-- 我的任务区域 -->
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<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 SurveyItem from '@/components/SurveyItem/Index.vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
/**
|
/**
|
||||||
@@ -21,23 +27,27 @@ function handleSurveyClick(survey: { sn: any }) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
const surveys = computed(() => {
|
||||||
|
// 取前三个元素
|
||||||
|
return _surveys.value.slice(0, 3);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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">
|
<van-cell v-for="survey in surveys" :key="survey" class="list-item">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<survey-item :survey="survey" @click="handleSurveyClick(survey)" />
|
<survey-item :survey="survey" @click="handleSurveyClick(survey)" />
|
||||||
</template>
|
</template>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
</van-list>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@use '@/assets/css/theme';
|
@use '@/assets/css/theme';
|
||||||
|
|
||||||
.list-container {
|
.list-container {
|
||||||
max-height: 30vh;
|
// max-height: 30vh;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
|
|
||||||
.list-item {
|
.list-item {
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { fetchHistory } from '@/hooks/request/useSearch';
|
||||||
import Layout from '@/components/Layout/CommonLayout.vue';
|
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 { Delete } from '@element-plus/icons-vue';
|
||||||
import { handleSearch } from '../../Hooks/useSurveySearch';
|
import { handleSearch } from '../../Hooks/useSurveySearch';
|
||||||
|
|
||||||
useFetchRecommon();
|
useFetchRecommon();
|
||||||
|
|
||||||
|
const { history } = fetchHistory();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -21,8 +24,9 @@ useFetchRecommon();
|
|||||||
:hit="false"
|
:hit="false"
|
||||||
round
|
round
|
||||||
v-for="tag in list"
|
v-for="tag in list"
|
||||||
>{{ tag.key_word }}</el-tag
|
|
||||||
>
|
>
|
||||||
|
{{ tag.key_word }}
|
||||||
|
</el-tag>
|
||||||
</el-space>
|
</el-space>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
||||||
@@ -35,9 +39,9 @@ useFetchRecommon();
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
<el-space>
|
<section style="display: flex; flex-wrap: wrap">
|
||||||
<el-tag
|
<el-tag
|
||||||
style="color: black"
|
style="color: black; margin: 3px"
|
||||||
color="white"
|
color="white"
|
||||||
:hit="false"
|
:hit="false"
|
||||||
round
|
round
|
||||||
@@ -45,7 +49,7 @@ useFetchRecommon();
|
|||||||
v-for="tag in history"
|
v-for="tag in history"
|
||||||
>{{ tag }}</el-tag
|
>{{ tag }}</el-tag
|
||||||
>
|
>
|
||||||
</el-space>
|
</section>
|
||||||
</layout>
|
</layout>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { ref } from 'vue';
|
|||||||
// 从服务器接受的列表内容
|
// 从服务器接受的列表内容
|
||||||
const list = ref<HotSearch[]>([]);
|
const list = ref<HotSearch[]>([]);
|
||||||
// 历史列表
|
// 历史列表
|
||||||
const history = ref<Set<string>>(new Set());
|
const history = ref<string[]>([]);
|
||||||
initialHistory();
|
initialHistory();
|
||||||
|
|
||||||
async function useFetchRecommon() {
|
async function useFetchRecommon() {
|
||||||
@@ -28,7 +28,7 @@ async function initialHistory() {
|
|||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
data.data.forEach((item: { id: number; keyword: string }) => {
|
data.data.forEach((item: { id: number; keyword: string }) => {
|
||||||
history.value.add(item.keyword);
|
history.value.push(item.keyword);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user