这个 TypeError 是否与错误的 this.$emit 有关?
2017-06-08
241
我正在构建一个组件,该组件应该从父级获取对象数组,显示它们并允许删除某些对象(=子级向父级发送一个新数组)。
上一个答案 对于理解子级 -> 父级通信非常有用,但我现在陷入了一个我无法理解的错误:
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
正确吗?
2个回答
有两个问题:
-
您的
_.filter
返回一个数组,因此您不会发出用户,而是发出包含用户的数组。该过滤器也完全没有必要,因为p
已经是您要过滤的用户对象。但该代码不是导致错误的原因。 -
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 Borg
2017-06-08
根据 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>
WoJ
2017-06-08