在vue中慎用箭头函数
以上标题其实是vue中的错误信息,但是由于标题的长度限制只能显示那么多。在此我将贴出完整的错误来分析。
![]()
文字错误描述:
vue.esm.js?efeb:591 [Vue warn]: Error in callback for watcher "permissionGroup": "TypeError: Cannot set property 'name' of undefined"
found in
---> <Permission> at src/pages/manage/rbac/Permission.vue
<ElMain>
<ElContainer>... (1 recursive calls)
<App> at src/App.vue
<Root>
warn @ vue.esm.js?efeb:591
logError @ vue.esm.js?efeb:1737
globalHandleError @ vue.esm.js?efeb:1732
handleError @ vue.esm.js?efeb:1721
run @ vue.esm.js?efeb:3235
flushSchedulerQueue @ vue.esm.js?efeb:2981
(anonymous) @ vue.esm.js?efeb:1837
flushCallbacks @ vue.esm.js?efeb:1758
Promise.then (async)
microTimerFunc @ vue.esm.js?efeb:1806
nextTick @ vue.esm.js?efeb:1850
queueWatcher @ vue.esm.js?efeb:3068
update @ vue.esm.js?efeb:3209
notify @ vue.esm.js?efeb:697
mutator @ vue.esm.js?efeb:844
setPermissionNode @ manager.js?b371:29
wrappedMutationHandler @ vuex.esm.js?358c:697
commitIterator @ vuex.esm.js?358c:389
(anonymous) @ vuex.esm.js?358c:388
_withCommit @ vuex.esm.js?358c:495
commit @ vuex.esm.js?358c:387
boundCommit @ vuex.esm.js?358c:335
(anonymous) @ manager.js?b371:20
Promise.then (async)
addPermissionGroup @ manager.js?b371:17
wrappedActionHandler @ vuex.esm.js?358c:704
dispatch @ vuex.esm.js?358c:426
boundDispatch @ vuex.esm.js?358c:332
mappedAction @ vuex.esm.js?358c:880
permissionGroupSubmit @ Permission.vue?2b09:115
click @ Permission.vue?0528:162
invoker @ vue.esm.js?efeb:2027
Vue.$emit @ vue.esm.js?efeb:2538
handleClick @ index.js?a811:1
invoker @ vue.esm.js?efeb:2027
fn._withTask.fn._withTask @ vue.esm.js?efeb:1826
vue.esm.js?efeb:1741 TypeError: Cannot set property 'name' of undefined
at VueComponent.permissionGroup (Permission.vue?2b09:121)
at Watcher.run (vue.esm.js?efeb:3233)
at flushSchedulerQueue (vue.esm.js?efeb:2981)
at Array.eval (vue.esm.js?efeb:1837)
at flushCallbacks (vue.esm.js?efeb:1758)
vue出错部分代码分析
data: function () {
return {
addPermissionPanelVisible: false,
form: {
name: '',
is_open: '1',
is_public: '1'
},
...
watch: {
permissionGroup: (curlVla, oldVal) => {
this.form.name = null;
return JSON.stringify(this.permissionGroup);
}
}
错误原因分析
在watch侦听器中我们监听permissionGroup的变化,如果permissionGroup变化时则执行后边的处理函数。貌似一切都没有问题
。其实我们再回到错误提醒来看看。重点在property 'name' undefined
这个错误对应的代码行是this.form.name = null;
我们知道this.form.name就是当前vue实例中的data中的form对象的name属性name为什么没有找到呢?
这儿我们要搞清楚es6中箭头函数的特殊之处。箭头函数自动绑定了上下文对象到this中。那么就说明我们在箭头函数中引用的this不再是vue实例。
验证错误
下边我们分别使用箭头函数和不使用箭头函数打印下this
使用箭头函数
不使用箭头函数
可以很明显的看出来两个是完全不同的对象,而使用普通函数时this才是vueComponent对象。所以大家在使用es6特性的时候一定要注意。在vue的内部一定要注意箭头函数对于this对象的影响。当然如果你非要使用箭头函数也是可以的,我们通常的一个做法是在组件data函数中中定义var _self = this然后再组件中用_self引用vue实例。