【问题标题】:Error: "Error in v-on handler: "TypeError: this.filter is undefined"" in a list rendering in vue?错误:“v-on 处理程序中的错误:“TypeError:this.filter 未定义”在 vue 中的列表呈现中?
【发布时间】:2020-11-27 10:41:57
【问题描述】:

我正在尝试构建一个组件来创建过滤器按钮,然后通过事件总线将过滤器对象中的类型属性发送到我的应用程序的其他地方处理。但是,当我在数据部分添加对象数组(过滤器)时,我收到 this 的错误。单击按钮时未定义过滤器。

我想将过滤器数组保留在此组件中,因为我还尝试将活动类动态更改为已单击的任何按钮。

我错过了与道具有关的东西吗?当 data 和 v-for 在另一个组件上时,为什么我无法显示按钮?为了解决这个问题,我一直在问自己这些问题。

<template>
  <div>
    <button
      v-for="(filter, index) in filters"
      :key="index"
      :class="{ active: index === activeItem }"
      @click="emitFilter(), selectItem(index)"
      :filter="filter"
    >
      {{ filter.name }}
    </button>
  </div>
</template>

<script>
import EventBus from '@/components/EventBus'
export default {
  props: {
    filter: { type: String }
  },
  data() {
    return {
      activeItem: 0,
      filterResult: '',
      filters: [
        { name: 'All', type: 'all' },
        { name: 'Holidays', type: 'holiday' },
        { name: 'Seasons', type: 'season' },
        { name: 'Events', type: 'custom' }
      ]
    }
  },
  methods: {
    emitFilter() {
      this.filterResult = this.filter
      EventBus.$emit('filter-catagories', this.filterResult)
    },
    selectItem(index) {
      this.activeItem = index
    }
  }
}
</script>

我的按钮组件在过滤器组件中使用

<template>
  <div>
    <span>filters</span>
      <FilterBtn />
    </div>
  </div>
</template>

<script>
import FilterBtn from '@/components/FilterBtn'


export default {
  components: {
    FilterBtn
      }
  // data() {
  //   return {
  //     filters: [
  //       { name: 'All', type: 'all' },
  //       { name: 'Holidays', type: 'holiday' },
  //       { name: 'Seasons', type: 'season' },
  //       { name: 'Events', type: 'custom' }
  //     ]
  //   }
  // }
}
</script>

如您所见,注释部分是我最初使用过滤器的地方,但我必须将它们移动到按钮组件才能添加活动类。

【问题讨论】:

  • 你可能弄乱了v-for中参数的顺序,通常是(index, value)。此外,您应该避免覆盖道具名称。
  • @andypotato 顺序是正确的
  • 我只是对为什么 this.filter 未定义感到困惑。覆盖道具名称是什么意思@andypotato
  • @TylerMorales 你能告诉我们你在哪里使用你的组件吗?我猜您没有将道具传递给您的按钮组件?使用this.$props,您可以检查它是否可用
  • @Ifaruki 我刚刚编辑了帖子以反映这些变化

标签: javascript list vue.js vue-component v-for


【解决方案1】:

我假设您实际上是在尝试从 emitFilter() 中访问 v-for="(filter, index) in filters"filter 迭代器。为此,您需要在 @click 绑定中传递 filter 本身:

<button v-for="(filter, index) in filters"
        @click="emitFilter(filter)">

然后,您的处理程序可以直接使用该参数:

export default {
  methods: {
    emitFilter(filter) {
      this.filterResult = filter
      //...
    }
  }
}

【讨论】:

  • 谢谢!这正是我一直在寻找的。巧合的是,我只是在你发帖前几秒钟就想到了这一点。虽然不完全相同,但我所做的是在 @click 上将 filter.type 作为 emittFilter 的参数传递,然后在方法中使用它。
【解决方案2】:

您正在将一个名为 filter 的 prop 输入为 string 传递给您的组件。当您输出 {{ filter.name }} 时,您实际上指的是该属性,而不是您在 v-for 循环中创建的变量 filter

除非您将名为“filter”的属性传递给组件,否则该属性将是未定义的。因此输出filter.name 将导致此错误消息。

【讨论】:

  • 我想我只是对这个组件如何接收道具感到困惑。我以为道具是从父母传给孩子的
【解决方案3】:

是的,您没有将道具传递给您的组件,这就是它未定义的原因。

<FilterBtn filter="test" />

这里我传递了一个名为filter 的道具,其值为test

当然可以传递动态道具。绑定就行了。

<FilterBtn :filter="yourData" />

我要问:你传递的是对象还是字符串?

因为你将你的 prop 定义为一个字符串,但你实际上将它用作一个对象

  {{ filter.name }}

也许您还应该将类型设置为 Object。

  props: {
    filter: { type: Object }
  },

【讨论】:

  • 一个对象。我的主要目标是从过滤器数组中获取类型,并在 emitFilter() 方法中的 this.filterResult 上使用它。很简单,我真正想做的只是将过滤器的类型('all','holiday'...)传递给单击按钮。我想发出类型。