Vue.js将搜索框移至Header组件后搜索结果无法渲染如何解决?
核心实现思路
你原本的实现已经用路由query参数传递搜索关键词,利用这个特性就可以实现Header和搜索结果页的通信,无需引入额外的状态管理工具,方案轻量且支持搜索页链接分享、浏览器前进后退操作。
第一步:调整Header组件
Header组件只负责收集搜索关键词、跳转到搜索结果页即可,不需要处理搜索请求逻辑:
- 补充Header组件的script逻辑:
export default { data() { return { search: '', // 其他原有变量保持不变 } }, methods: { goSearch() { const trimSearch = this.search.trim() if (!trimSearch) return // 跳转到搜索结果页并携带搜索参数 this.$router.push({ path: '/search', query: { search: trimSearch } }) } }, // 其他原有逻辑保持不变 }
- 修正Header的template代码,修复原有嵌套router-link导致的交互问题:
<template> <header class="header"> <!-- 阻止form默认提交刷新行为 --> <form class="search" @submit.prevent="goSearch"> <input v-model="search" @keyup.enter="goSearch" placeholder="Search recipe" /> <button type="submit"> <font-icon class="icon" :icon="['fas', 'search']"></font-icon> </button> </form> <!-- 其他原有菜单逻辑保持不变 --> </header> </template>
第二步:调整搜索结果组件
把原本的搜索请求逻辑迁移到搜索结果组件,监听路由query的search参数变化,自动触发搜索请求:
<script> import RecipeItem from "../recipe/RecipeItem"; import { baseApiUrl } from "@/global"; import axios from "axios"; import PageTitle from "../template/PageTitle"; export default { name: "SearchResult", components: { PageTitle, RecipeItem }, data() { return { recipes: [], } }, methods: { async getRecipes(keyword) { // 关键词为空时清空结果 if (!keyword) { this.recipes = [] return } try { // 对关键词编码避免特殊字符导致请求异常 const url = `${baseApiUrl}/search?search=${encodeURIComponent(keyword)}`; const res = await axios(url) this.recipes = res.data } catch (err) { console.error('搜索请求失败', err) this.recipes = [] } } }, watch: { // 监听路由搜索参数变化,自动触发搜索 '$route.query.search': { immediate: true, handler(newVal) { this.getRecipes(newVal) } } }, }; </script>
搜索结果组件的template部分保持你现有写法即可。
如果后续项目规模扩大,多个组件都需要共享搜索状态,也可以引入Pinia/Vuex统一存储搜索关键词、搜索结果,跨组件通信会更方便。
内容的提问来源于stack exchange,提问作者will
相关产品推荐
相关产品推荐

