这个 TypeError 是否链接到错误的 this.$emit?

Is this TypeError linked to a wrong this.$emit?

我正在构建一个组件,该组件应该从 parent 中获取 Objects 数组,显示它们并允许删除某些 Objects(= child 向 parent 发送一个新数组)。

A 对于理解 child -> parent 通信非常有用,但我现在陷入了一个我不理解的错误:

Vue.component('search-box', {
  template: '#search-box-template',
  props: ['who'],
  methods: {
    deleteID: function(p) {
      var user = _.filter(this.who, function(w) {
        return w.id === p.id
      })
      this.$emit('delete-id', user)
    }
  }
})
var vm = new Vue({
  el: '#root',
  data: {
    who: [{
      "name": "john",
      "id": 1
    }, {
      "name": "mary",
      "id": 2
    }]
  }
})
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


<div id="root">
  Hello in parent
  <search-box v-bind:who="who" v-on:delete-id="who"></search-box>
  who is: {{who}}
</div>

<template id="search-box-template">
    <div>
        <ul>
            <li v-for="p in who">person: {{p.name}}, id: {{p.id}} <button v-on:click="deleteID(p)">delete</button></li>
        </ul>
    </div>
</template>

运行 此代码正确列出了用户,但是当我试图删除一个时,我进入了控制台

vue.js:1739 Uncaught TypeError: fns[i].apply is not a function
    at VueComponent.invoker (vue.js:1739)
    at VueComponent.Vue.$emit (vue.js:2210)
    at VueComponent.deleteID (search.html:31)
    at Proxy.boundFn (vue.js:170)
    at click (eval at makeFunction (vue.js:9323), <anonymous>:2:164)
    at HTMLButtonElement.invoker (vue.js:1743)
invoker @   vue.js:1739
Vue.$emit   @   vue.js:2210
deleteID    @   search.html:31
boundFn @   vue.js:170
click   @   VM9358:2
invoker @   vue.js:1743

这个错误是什么意思? $emit 正确吗?

有两个问题:

  1. _.filter returns 一个数组,所以你不发出用户,而是一个包含用户的数组。该过滤器也完全没有必要,因为 p 已经是您要过滤的用户对象。但该代码不是错误的原因。
  2. v-on:delete-id="who" 将对象 (who) 传递给事件侦听器,但它需要一个函数。这就是引发错误的原因。

您的代码的工作版本如下所示:

Vue.component('search-box', {
  template: '#search-box-template',
  props: ['who'],
  methods: {
    deleteID: function(p) {
      this.$emit('delete-id', p)
    }
  }
})

var vm = new Vue({
  el: '#root',
  data: {
    who: [{
      "name": "john",
      "id": 1
    }, {
      "name": "mary",
      "id": 2
    }]
  },
  methods: {
    handleDelete(person) {
      const index = this.who.indexOf(person)
      this.who.splice(index, 1)
    }
  }
})
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


<div id="root">
  Hello in parent
  <search-box v-bind:who="who" v-on:delete-id="handleDelete"></search-box>
  who is: {{who}}
</div>

<template id="search-box-template">
    <div>
        <ul>
            <li v-for="p in who">person: {{p.name}}, id: {{p.id}} <button v-on:click="deleteID(p)">delete</button></li>
        </ul>
    </div>
</template>

继 Linus 的出色回答之后,下面的记录是我更正的代码,当用户被删除时它会发出和数组。

Vue.component('search-box', {
  template: '#search-box-template',
  props: ['who'],
  methods: {
    deleteID: function(p) {
                var user = _.filter(this.who, function (w) {
                return w.id != p.id
            })
      this.$emit('delete-id', user)
    }
  }
})

var vm = new Vue({
  el: '#root',
  data: {
    who: [{
      "name": "john",
      "id": 1
    }, {
      "name": "mary",
      "id": 2
    }]
  },
  methods: {
    handleDelete(users) {
      this.who = users
    }
  }
})
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


<div id="root">
  Hello in parent
  <search-box v-bind:who="who" v-on:delete-id="handleDelete"></search-box>
  who is: {{who}}
</div>

<template id="search-box-template">
    <div>
        <ul>
            <li v-for="p in who">person: {{p.name}}, id: {{p.id}} <button v-on:click="deleteID(p)">delete</button></li>
        </ul>
    </div>
</template>