Vue 中递归调用 method ,报 Maximum call stack size exceeded 错误?

更新

复现代码:
https://codepen.io/jiaxi0331/...

题目描述

在 vue 中执行
this.$options.methods.method.call(vue.$parent, ...) 绑定 this.$parent 失败。

想知道 call方法绑定 this.$parent 失败的而原因,这里递归调用 this.$options.name 会一直为最开始调用组件的 name.

题目来源及自己的思路

实现一个跨组件的事件触发方法 dispatch 时,递归查找指定的组件。

相关代码 粘贴代码文本(请勿用截图)

export default {
  methods: {
    dispatch(componentName, event, value) {
      if (this.$options.name === componentName) {
        this.$emit(event, value);
      } else if (this.$parent){
        const parent = this.$parent;
        return this.dispatch.call(parent, componentName, event, value); // Error
      }
    }

    // broadcast(componentName, event, value) {}
  }
};

你期待的结果是什么?实际看到的错误信息又是什么?

call(this.$parent) 之后,能够将 this 绑定到 parent 实例上。

看到实际的错误信息:
Error in v-on handler: "RangeError: Maximum call stack size exceeded"

问题出现的环境背景及自己尝试过哪些方法

vue 2.6.1

将 dispatch 封装为一个独立的方法

相关代码 粘贴代码文本(请勿用截图)

function dispatch(componentName, event, value) {
  if (this.$options.name === componentName) {
    this.$emit(event, value);
  } else {
    const parent = this.$parent || this.$root;
    return dispatch.call(parent, componentName, event, value);
  }
}
export default {
  methods: {
    dispatch(componentName, event, value) {
      dispatch.call(this, componentName, event, value);
    }

    // broadcast(componentName, event, value) {}
  }
};

你期待的结果是什么?实际看到的错误信息又是什么?

能够正常工作了,所以我这里产生疑问,MDN 上关于 this 的解释是调用该方法的对象,我没想明白这里为什么会报错,求解答。

阅读 3.3k
2 个回答

const parent = this.$parent || this.$root;

this$root 时就会跳不出去了,死循环

因为method已经bind到实例了,比如执行 fn.bind(obj1).call(obj2),此时fn函数的this会指向obj1,并不会指向obj2。
所以楼主在函数中递归调用已绑定Vue组件实例的method,会导致死循环,就会报 Maximum call stack size exceeded。

    // 递归死循环
methods: {
    test() {
      const obj = {app: 'obj'}
      this.test.call(obj)
      console.log(this) // VueComponent
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题