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

Vue项目数组传值至组件异常:动态路由失效、页面空白及调度器刷新错误排查

问题分析与解决方案

咱们先拆解下你遇到的核心问题:

  1. 动态路由未配置/参数传递错误:点击「Details」按钮跳转时,没有设置带参数的动态路由规则,也没正确传递单个饮品的标识,导致页面无法匹配组件呈现空白。
  2. props类型不匹配:警告显示你把整个drinks数组传给了SingleDrink组件,而该组件的props要求是单个对象,类型冲突触发了Vue调度器的内部错误。
  3. 组件渲染逻辑混淆:Drinks.vue里直接循环渲染多个SingleDrink组件,这是列表展示逻辑,但你实际需要的是通过路由跳转单独展示单个饮品的详情页。

接下来一步步解决这些问题:

1. 配置动态路由规则

首先在路由配置文件(通常是src/router/index.js)中,添加带参数的动态路由,用于匹配单个饮品的详情页:

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import SingleDrink from '../views/SingleDrink.vue' // 确保组件路径正确

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    // 用:productName作为动态参数,匹配饮品名称
    path: '/drink/:productName',
    name: 'SingleDrink',
    component: SingleDrink,
    // 开启props自动传递路由参数,方便组件直接接收
    props: true
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

2. 修复Home.vue的路由跳转逻辑

在Home.vue中完善route方法,确保跳转时传递单个饮品的名称作为路由参数:

首先在script部分定义跳转方法:

methods: {
  route(item) {
    this.$router.push({
      name: 'SingleDrink',
      params: { productName: item.product }
    })
  }
}

同时修正模板里的拼写错误(你数据源里是price/product,模板里写了cijena/proizvod):

<div class="overlay-content">
  <h2>{{items.price}} kn</h2>
  <p>{{items.product}}</p>
  <button @click.prevent="route(items)" class="btn btn-default add-to-cart">Details</button>
  <router-link to="/cart" class="btn btn-default add-to-cart"><i class="fa fa-shopping-cart"></i>Add to cart</router-link>
</div>

3. 修改SingleDrink组件,匹配单个饮品数据

现在SingleDrink组件需要通过路由参数获取饮品名称,再从数组中匹配对应的单个元素。你可以把drinks数组抽成全局数据(比如Vuex),这里先演示组件内部定义的方式:

<template>
  <div id="SingleDrink" v-if="selectedDrink">
    <h1>{{selectedDrink.product}}</h1>
    <img :src="selectedDrink.url" alt="Drink image">
    <p>Price: {{selectedDrink.price}} kn</p>
  </div>
  <div v-else>
    <p>Drink not found!</p>
  </div>
</template>

<script>
export default {
  props: {
    // 接收路由传递的productName参数
    productName: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      drinks: [ 
        {product:"Wine", price: 149.99, url: require('../assets/images/grasevina.jpg')}, 
        {product:"Beer", price: 12.99, url: require('../assets/images/corona.jpg')}, 
        {product:"Vodka Smirnoff", price: 119.99, url: require('../assets/images/smirnoff.jpg')}, 
        {product:"Cocktail Malibu", price: 89.99, url: require('../assets/images/malibu.jpg')}, 
        {product:"Jack Daniels Honey", price: 169.99, url: require('../assets/images/jack_daniels.jpg')}, 
        {product:"Strawberry liqueur", price: 149.99, url: require('../assets/images/liker-malina.jpg')} 
      ],
      selectedDrink: null
    }
  },
  mounted() {
    // 根据路由参数匹配单个饮品
    this.selectedDrink = this.drinks.find(drink => drink.product === this.productName)
  }
}
</script>

4. 清理冗余逻辑(可选)

如果你不需要在Drinks.vue里循环渲染SingleDrink组件,可以移除那部分代码——现在我们是通过路由跳转展示详情,而非在列表页渲染多个详情组件。如果Drinks.vue是列表页,保留列表展示逻辑即可。

关于调度器刷新错误的原因

之前的警告是因为你错误地将整个drinks数组传给了SingleDrink组件的SingleDrink props(比如路由跳转时误传了数组),而该props要求是Object类型,类型不匹配导致Vue内部调度器处理出错。现在通过路由参数传递单个饮品标识,再在组件内部匹配对应元素,就解决了类型冲突问题。

内容的提问来源于stack exchange,提问作者Jan Tuđan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 21:17:36