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

Vue Router动态路由传参请求详情id为undefined解决方法

问题现象

Vue.js 项目使用 vue-router 动态路由实现从职位列表页跳转到详情页时,URL 地址栏可以正常显示传入的 id 参数,但详情页无法加载数据,控制台报错:GET http://localhost:1337/jobinfos/undefined。手动将请求参数里的 id 写死为 1 时,接口能正常返回数据且控制台可打印返回结果,但页面依旧无法正常展示数据。


问题原因
  • 路由参数获取逻辑错误:默认情况下 vue-router 不会自动把动态路由段参数注入为组件 props,直接声明props:['id']取this.id会得到undefined,直接导致请求地址携带undefined。
  • 响应式变量缺失:两个组件都没有在data中提前声明jobinfos变量,接口返回赋值后数据不是响应式的,无法触发视图更新,这也是手动写死id时控制台能拿到数据但页面不渲染的核心原因。
  • 列表页数据源不匹配:列表循环用的是showJobs,但接口请求返回后赋值给了this.jobinfos,没有做同步赋值的话,循环拿到的item本身就可能缺失id字段,导致跳转传参异常。
  • 渲染逻辑错误:单条职位详情接口返回的是单个对象而非数组,直接对返回对象用v-for遍历,模板无法正确读取字段值。
  • 基础语法笔误:两个组件的导出语句都写成了export defaul,漏了末尾的t,会直接触发组件编译异常。
  • 跳转冲突:列表页存在空href的<a>标签,点击会触发整页刷新,和router-link的单页路由跳转逻辑冲突。
  • v-for 用法不规范:列表循环的key用了index而非唯一的item.id,容易出现渲染复用导致的异常。

修复步骤

1. 先确认路由配置

如果要使用props接收路由参数,必须在路由配置中开启props传参:

// router/index.js 中的详情页路由配置
{
  path: '/detail/:id', // 动态路由参数名为id
  name: 'JobDetail',
  component: () => import('../views/JobDetail.vue'),
  props: true // 必须加这行,路由参数才会注入为组件props
}

如果不想开启props模式,后续在详情页直接用this.$route.params.id取参数即可。

2. 修复列表页 Jobs.vue 代码

<template>
  <!-- 循环数据源和接口返回变量保持一致,key用唯一id -->
  <div class="job-item" v-for="item in showJobs" :key="item.id">
    <!-- 移除空href,避免触发整页刷新 -->
    <a>
      <h3 class="mleft-27">{{ item.position }}</h3>
    </a>
    <img src="../assets/recruit/years.svg" alt="" />
    <b>{{ item.exprerience }}</b>
    <img src="../assets/recruit/luong.svg" alt="" />
    <b>{{ item.salary }}</b>
    <img src="../assets/recruit/diadiem.svg" alt="" />
    <b>{{ item.headequarters }}</b>
    <h6>{{ item.createdAt }}</h6>
    <div class="list-info-job" v-html="item.content">
      <router-link tag="a" :to="`/detail/${item.id}`">
        <button class="btn-detail">See Detail</button>
      </router-link>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
// 修正export default笔误
export default {
  // 提前声明所有响应式变量
  data() {
    return {
      jobinfos: [],
      showJobs: []
    }
  },
  mounted() {
    // 页面挂载时触发列表请求
    this.getJobs()
  },
  methods: {
    async getJobs() {
      // 统一async/await写法,不要混用then/catch
      try {
        const response = await axios.get('http://localhost:1337/jobinfos')
        this.jobinfos = response.data
        // 如果需要过滤展示数据,在此处给showJobs赋值
        this.showJobs = this.jobinfos
      } catch (e) {
        console.error('获取职位列表失败:', e)
      }
    },
  }
}
</script>

3. 修复详情页代码

<template>
  <!-- 单条详情是对象,不需要v-for,加加载态判断 -->
  <div v-if="jobinfos" class="detail-wrap">
    <div class="info-detail">
      <div>
        <h6>Job Requirements</h6>
        <ul v-html="jobinfos.requirements"></ul>
      </div>
    </div>
    <div class="info-detail">
      <div>
        <h6>Skills</h6>
        <ul v-html="jobinfos.skills"></ul>
      </div>
    </div>
    <div class="info-detail">
      <div>
        <h6>Interests</h6>
        <ul v-html="jobinfos.interests"></ul>
      </div>
    </div>
  </div>
  <div v-else>职位信息加载中...</div>
</template>

<script>
import axios from 'axios'
// 修正export default笔误
export default {
  // 路由开了props就保留,没开就删掉这行
  props:['id'],
  data() {
    return {
      jobinfos: null // 单条详情初始值设为null,方便做加载判断
    }
  },
  mounted(){
    this.getdetail();
  },
  methods: {
    async getdetail() {
      try {
        // 兼容两种取参方式,避免参数取不到
        const jobId = this.id || this.$route.params.id
        const res = await axios.get(`http://localhost:1337/jobinfos/${jobId}`)
        this.jobinfos = res.data;
        console.log('详情数据:', res.data)
      } catch (e) {
        console.error('获取职位详情失败:', e)
      }
    },
  }
}
</script>

验证要点

改完后按顺序检查:

  1. 列表页接口返回的每条数据是否存在id字段,点击详情按钮时地址栏的id和列表项id一致
  2. 详情页请求发起前,打印拿到的jobId确认不是undefined
  3. 单条详情接口返回的对象,直接访问requirements、skills、interests字段是否有值

内容的提问来源于stack exchange,提问作者Nguyễn Thế Hưng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:54:16