[Vue warn]: Error in callback for watcher "xxxxxxxxx": "TypeError: Cannot set property 'name' of

在vue中慎用箭头函数

以上标题其实是vue中的错误信息,但是由于标题的长度限制只能显示那么多。在此我将贴出完整的错误来分析。
错误描述
文字错误描述:

vue.esm.js?efeb:591 [Vue warn]: Error in callback for watcher "permissionGroup": "TypeError: Cannot set property 'name' of undefined"

found in

--->  at src/pages/manage/rbac/Permission.vue
       
         ... (1 recursive calls)
            at src/App.vue
             
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实例。

你可能感兴趣的:(vuejs,前端,JavaScript,vue-js)