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

Vue3循环对象数组时,如何为每个组件设置不同点击事件?

解决方案:传递函数作为Props实现不同点击事件

问题原因

你当前在cardPropsArray里把scrollFunction设为字符串(比如"musicScroll()"),但Vue无法直接将字符串解析为组件内的方法,所以触发点击时会抛出类型错误:$props.cardProperties.scrollFunction 不是一个函数。

下面提供几种可行的解决方式:

方法1:直接传递组件方法的引用(简单直接)

把父组件里的滚动方法直接作为引用传入数组,而非字符串形式:

App.vue 修改代码

<script>
export default {
  data() {
    return {
      cardPropsArray: [
        {
          id: "music",
          scrollFunction: this.musicScroll, // 直接传递方法引用
          title: "Musik",
          icon: "fa-solid fa-music",
          text: "/play"
        },
        {
          id: "mao",
          scrollFunction: this.maoScroll,
          title: "Med Andra Ord",
          icon: "fa-solid fa-hourglass-end",
          text: "/MAO"
        }
      ]
    };
  },
  methods: {
    musicScroll() {
      const musicDiv = document.getElementById("music");
      if(musicDiv != null){
        musicDiv.scrollIntoView({behavior: 'smooth'});
      }
    },
    maoScroll() {
      const maoDiv = document.getElementById("mao");
      if(maoDiv != null){
        maoDiv.scrollIntoView({behavior: 'smooth'});
      }
    }
  }
};
</script>

子组件(card-container)简化代码
可以删除子组件内的滚动方法和冗余的cardProps数据,直接使用props传入的函数:

<template>
  <div 
    @click="cardProperties.scrollFunction" 
    :id="cardProperties.id" 
    class="flex text-text-color justify-around text-center bg-container-color h-1/6 w-2/12 rounded-3xl shadow-lg m-4 cursor-pointer ease-in-out duration-500 hover:bg-container-hover-color opacity-95"
  >
    <div class="py-6">
      <h2>{{cardProperties.title}}</h2>
      <font-awesome-icon class="h-12 my-4" :icon="cardProperties.icon" />
      <p>{{cardProperties.text}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'card-container',
  props: {
    cardProperties: {
      type: Object,
      required: true
    }
  }
};
</script>

方法2:通过事件触发(Vue推荐的父子通信方式)

如果不想把方法直接传入子组件,可以让子组件点击时触发事件,父组件根据卡片ID处理滚动逻辑:

子组件修改代码

<template>
  <div 
    @click="handleCardClick" 
    :id="cardProperties.id" 
    class="flex text-text-color justify-around text-center bg-container-color h-1/6 w-2/12 rounded-3xl shadow-lg m-4 cursor-pointer ease-in-out duration-500 hover:bg-container-hover-color opacity-95"
  >
    <div class="py-6">
      <h2>{{cardProperties.title}}</h2>
      <font-awesome-icon class="h-12 my-4" :icon="cardProperties.icon" />
      <p>{{cardProperties.text}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'card-container',
  props: {
    cardProperties: {
      type: Object,
      required: true
    }
  },
  methods: {
    handleCardClick() {
      this.$emit('card-click', this.cardProperties.id); // 触发事件并传递卡片ID
    }
  }
};
</script>

App.vue 修改代码

<template>
  <card 
    v-for="cardProperties in cardPropsArray"
    :key="cardProperties.text"
    :cardProperties="cardProperties"
    @card-click="handleScroll"
  />
</template>

<script>
export default {
  data() {
    return {
      cardPropsArray: [
        {
          id: "music",
          title: "Musik",
          icon: "fa-solid fa-music",
          text: "/play"
        },
        {
          id: "mao",
          title: "Med Andra Ord",
          icon: "fa-solid fa-hourglass-end",
          text: "/MAO"
        }
      ]
    };
  },
  methods: {
    handleScroll(id) {
      const targetDiv = document.getElementById(id);
      if(targetDiv) {
        targetDiv.scrollIntoView({behavior: 'smooth'});
      }
    }
  }
};
</script>

方法3:统一子组件内的滚动逻辑(精简代码)

两个滚动方法逻辑高度相似,仅目标ID不同,可以直接在子组件内根据卡片ID处理滚动,无需传递函数:

子组件修改代码

<template>
  <div 
    @click="handleScroll" 
    :id="cardProperties.id" 
    class="flex text-text-color justify-around text-center bg-container-color h-1/6 w-2/12 rounded-3xl shadow-lg m-4 cursor-pointer ease-in-out duration-500 hover:bg-container-hover-color opacity-95"
  >
    <div class="py-6">
      <h2>{{cardProperties.title}}</h2>
      <font-awesome-icon class="h-12 my-4" :icon="cardProperties.icon" />
      <p>{{cardProperties.text}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'card-container',
  props: {
    cardProperties: {
      type: Object,
      required: true
    }
  },
  methods: {
    handleScroll() {
      const targetDiv = document.getElementById(this.cardProperties.id);
      if(targetDiv) {
        targetDiv.scrollIntoView({behavior: 'smooth'});
      }
    }
  }
};
</script>

App.vue 简化数组
删除cardPropsArray里的scrollFunction字段即可:

cardPropsArray:[
  {
    id: "music",
    title: "Musik",
    icon: "fa-solid fa-music",
    text: "/play"
  },
  {
    id: "mao",
    title: "Med Andra Ord",
    icon: "fa-solid fa-hourglass-end",
    text: "/MAO"
  }
]

内容的提问来源于stack exchange,提问作者Kron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 20:42:02