You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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重新获取数据:

  1. 保持现有路由配置:你的路由已经正确设置了:movieId参数和props: true,无需修改。
  2. 修改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传递:

  1. 修改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>
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:09:57