Vue3中父组件传递响应式genreId给子组件失败问题排查
Vue组件通信问题:GameGrid无法接收genreId的解决方案
问题核心原因
- App组件中
selectedGenreId非响应式变量:用let selectedGenreId = null定义的普通变量,Vue无法追踪其变化,导致更新后无法同步给GameGrid组件,watch监听器也不会触发。 - 事件名规范(可选优化):GenreList发射的
genreId驼峰事件名,父组件用genre-id短横线监听虽能被Vue自动转换,但统一命名风格更易维护。
修正后的代码
1. App组件(修复响应式核心问题)
<template> <div> <div class="p-2"> <Navbar /> </div> <div class="grid grid-cols-12 mt-5"> <div class="hidden lg:block col-span-3 pl-3"> <GenreList @genre-id="handleGenreId"/> </div> <div class="col-span-12 lg:col-span-9 px-4"> <GameGrid :selectedGenreId="selectedGenreId" /> </div> </div> </div> </template> <script setup> import { ref } from 'vue' import Navbar from '@/components/NavBar.vue' import GameGrid from '@/components/GameGrid.vue' import GenreList from './components/GenreList.vue' // 改为响应式ref变量 const selectedGenreId = ref(null) function handleGenreId(id) { selectedGenreId.value = id // ref变量修改需通过.value } </script>
2. GenreList组件(可选:统一事件名风格)
将发射的事件名改为短横线风格,与父组件监听保持一致:
<!-- 修改点击事件的$emit部分 --> <p @click="$emit('genre-id', genre.id)" class="text-lg cursor-pointer hover:underline">{{ genre.name }}</p>
3. GameGrid组件(无需修改)
当前逻辑正确,只要父组件传递的selectedGenreId变为响应式,watch(props.selectedGenreId)就能正常监听变化并重新调用fetchGames获取对应分类的游戏数据。
验证效果
- 页面首次加载时,
selectedGenreId为null,GameGrid会加载全部游戏(需接口支持无genre参数的请求)。 - 点击GenreList中的分类时,
selectedGenreId响应式更新,GameGrid会自动重新请求对应分类的游戏数据。
内容的提问来源于stack exchange,提问作者godisgay
相关产品推荐
相关产品推荐

