Vue3 Router路径配置:实现电影卡片跳转对应详情页
解决Vue路由跳转动态详情页并展示对应数据的问题
1. 给电影数据补充唯一标识(Firebase文档ID)
Firebase每个文档都自带唯一id,先把这个ID加入到获取的电影数据中,作为后续匹配详情页的依据:
const fetchMovies = async () => { try { const querySnapshot = await getDocs(filmsRef); const moviesData = querySnapshot.docs.map(doc => ({ id: doc.id, // 新增文档ID作为唯一标识 link: doc.data().title, imgUrl: doc.data().img, imgAlt: doc.data().alt, status: doc.data().status, })); movies.value = moviesData; console.log(moviesData); loader.value = false; } catch (error) { console.error('Error fetching movies:', error); } };
2. 配置动态路由
在路由配置文件(如router/index.js)中添加带参数的动态路由,用来匹配不同电影的详情页:
import { createRouter, createWebHistory } from 'vue-router' import FilmsInfo from '@/views/FilmsInfo.vue' // 替换成你的详情页组件路径 const routes = [ // 其他已有路由 { path: '/films-info/:filmId', // :filmId 是动态参数,接收电影ID name: 'FilmsInfo', component: FilmsInfo, props: true // 开启后组件可直接接收路由参数 } ] const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes }) export default router
3. 修改卡片跳转逻辑
在films组件中,更新点击方法,跳转时带上当前电影的ID参数:
<script setup> import { ref } from 'vue'; import { useRouter } from 'vue-router'; const router = useRouter(); // 修改跳转逻辑,传入电影ID const selectFilm = (film) => { router.push(`/films-info/${film.id}`); }; // 其他原有代码不变 defineProps({ films: { type: Array, required: true, default: () => [] }, title: { type: String, required: true, }, link: { type: String, required: false, }, imgUrl: { type: String, required: false, }, imgAlt: { type: String, required: false, }, }) </script>
4. 详情页获取并展示对应数据
创建/修改FilmsInfo.vue组件,通过路由参数拿到电影ID,再从Firebase拉取对应数据:
<script setup> import { ref, onMounted } from 'vue'; import { useRoute } from 'vue-router'; import { doc, getDoc } from 'firebase/firestore'; import { db } from '@/firebase/config'; // 引入你的Firebase配置文件 const route = useRoute(); const film = ref(null); const loader = ref(true); onMounted(async () => { try { // 从路由参数中取电影ID const filmId = route.params.filmId; // 从Firebase查询对应文档 const filmDoc = doc(db, 'films', filmId); // 'films'替换成你的集合名称 const docSnapshot = await getDoc(filmDoc); if (docSnapshot.exists()) { film.value = { id: docSnapshot.id, ...docSnapshot.data() }; } else { console.log('未找到对应电影'); } } catch (error) { console.error('获取电影详情失败:', error); } finally { loader.value = false; } }); </script> <template> <div v-if="loader">加载中...</div> <div v-else-if="film" class="film-info"> <h1>{{ film.title }}</h1> <img :src="film.img" :alt="film.alt" class="film-img"> <p>状态: {{ film.status }}</p> <!-- 其他需要展示的电影字段 --> </div> <div v-else>未找到该电影</div> </template>
补充说明
如果想用电影标题作为路由参数(而非文档ID),需要处理特殊字符:
- 跳转时用
router.push(/films-info/${encodeURIComponent(film.link)})编码 - 路由配置改成
path: '/films-info/:filmTitle' - 详情页获取时用
decodeURIComponent(route.params.filmTitle)解码后查询,但文档ID是唯一无冲突的,更推荐用ID方案。
内容的提问来源于stack exchange,提问作者arisha
相关产品推荐
相关产品推荐

