Ionic Vue中通过router-link向嵌套标签页传递动态对象Prop
问题描述
我正在Ionic+Vue项目中尝试通过router-link把电影数据对象传递到嵌套标签页MoviePage.vue,希望把这个对象作为prop接收后展示它的属性。试过用props传参、Provide/Inject等方法都没生效,想找更直接的解决办法。
当前代码实现如下:
Tab2Page.vue
<template> ... <ion-content :fullscreen="true"> <p v-if="!movieData">Loading...</p> <pre v-else> <ion-grid> <ion-row> <ion-col size="6" :key="movie.Id" v-for="movie in movieData.Data.Movies"> ... <ion-img :src="movie.LargePosterUrl"></ion-img> <ion-button :router-link="`/tab2/movie/${movie.Id}`" router-direction="forward">More info</ion-button> </ion-col> </ion-row> </ion-grid> </pre> </ion-content> ... </template> <script setup lang="ts"> ... import { ref, provide } from 'vue'; const movieData = ref(null); const fetchData = async () => { movieData.value = null; try { const res = await fetch('https://www.eventcinemas.com.au/Movies/GetNowShowing'); if (!res.ok) { throw new Error(`HTTP error! Status: ${res.status}`); } movieData.value = await res.json(); provide('someMovieData', movieData.value); } catch (error) { console.error(error); } }; fetchData(); </script>
routes -> index.ts
... const routes: Array<RouteRecordRaw> = [ ... { path: '/tabs/', component: TabsPage, children: [ ... { path: '/tab2/movie/:movieId', name: 'movieInfo', component: () => import('@/views/MoviePage.vue'), props: true } ] } ]; ...
MoviePage.vue
<template> <ion-page> ... <ion-content :fullscreen="true"> <!-- Full movie details such as: Name, image, release date, genre, director, etc. --> <p>{{ someMovieData }}</p> </ion-content> </ion-page> </template> <script setup lang="ts"> ... import { defineProps, inject } from 'vue'; const someMovieData = inject('someMovieData'); ... </script>
解决方案
方法一:通过路由ID参数获取数据(推荐,支持页面刷新)
这种方法最可靠,页面刷新后依然能通过ID重新获取数据:
- 保持现有路由配置:你的路由已经正确设置了
:movieId参数和props: true,无需修改。 - 修改MoviePage.vue接收参数并获取对应电影:
<template> <ion-page> ... <ion-content :fullscreen="true"> <p v-if="!movie">Loading...</p> <div v-else> <h2>{{ movie.Title }}</h2> <ion-img :src="movie.LargePosterUrl"></ion-img> <p>上映日期:{{ movie.ReleaseDate }}</p> <!-- 其他属性按需展示 --> </div> </ion-content> </ion-page> </template> <script setup lang="ts"> import { ref, onMounted } from 'vue'; import { useRoute } from 'vue-router'; const route = useRoute(); const movie = ref(null); // 方式1:若有单部电影查询接口,直接通过ID请求 const fetchMovieById = async () => { try { const res = await fetch(`https://www.eventcinemas.com.au/Movies/GetMovieById/${route.params.movieId}`); if (!res.ok) throw new Error('请求失败'); movie.value = await res.json(); } catch (err) { console.error(err); } }; // 方式2:若无单部接口,重新拉取列表后筛选对应电影 const fetchMovieFromList = async () => { try { const res = await fetch('https://www.eventcinemas.com.au/Movies/GetNowShowing'); if (!res.ok) throw new Error('请求失败'); const data = await res.json(); movie.value = data.Data.Movies.find((m: any) => m.Id === route.params.movieId); } catch (err) { console.error(err); } }; onMounted(() => { // 根据实际情况选择方式1或2 fetchMovieFromList(); }); </script>
方法二:通过路由state传递完整对象(适合无需刷新的场景)
如果不需要支持页面刷新,可以直接把电影对象通过路由state传递:
- 修改Tab2Page.vue的router-link:
<!-- 替换原字符串路由为对象形式,携带state数据 --> <ion-button :router-link="{ name: 'movieInfo', params: { movieId: movie.Id }, state: { movie: movie } }" router-direction="forward" > More info </ion-button>
- 修改MoviePage.vue获取state中的电影对象:
<template> <ion-page> ... <ion-content :fullscreen="true"> <p v-if="!movie">Loading...</p> <div v-else> <h2>{{ movie.Title }}</h2> <ion-img :src="movie.LargePosterUrl"></ion-img> <!-- 其他属性按需展示 --> </div> </ion-content> </ion-page> </template> <script setup lang="ts"> import { useRoute } from 'vue-router'; const route = useRoute(); const movie = route.state?.movie; </script>
注意:方法二中的state数据在页面刷新后会丢失,因此需要支持刷新场景时优先使用方法一。
内容的提问来源于stack exchange,提问作者Jeremy Chee
相关产品推荐
相关产品推荐

