Vue2.0的子元素自定义组件不能调用父元素的methods

代码如下:

<div id="counter-event-example">

  <p>{{ total }}</p>
     <button-counter v-on:click="incrementTotal"></button-counter>
     <button-counter v-on:click="incrementTotal"></button-counter>

</div>

<script>

Vue.component('button-counter', {
    template: '<button >{{ counter }}</button>',
        data: function () {
           return {
              counter: 0
           };
        }
});
        

new Vue({

el: '#counter-event-example',
    data: {
         total: 0
    },
    methods: {
         incrementTotal: function () {
            this.total += 1;
        }
    }

});
</script>

为什么button-counter添加的click事件不能调用父元素的methods里面的方法呢?

阅读 3.5k
3 个回答
  1. 监听事件不能在组件上监听,<button-counter v-on:click="incrementTotal"></button-counter> 这样写不对, Vue 会渲染组件的模板(template),所以应该在模板上监听,template: '<button v-on:click="incrementTotal">{{ counter }}</button>'

  2. 监听完事件,调用的问题,子组件只能调用自己组件内定义的方法。你可以这么样写。

Vue.component('button-counter', {
      template: '<button v-on:click="incrementTotal">{{ counter }}</button>',
      data: function () {
        return {
          counter: 0
        };
      },
      methods: {
        incrementTotal: function() {
          this.counter += 1
          this.$parent.incrementTotal() // 调用父组件上的方法
          // 如果调用根组件的方法,this.$root.incrementTotal()
        }
      }
    });

你应该是参考了这个例子:使用 v-on 绑定自定义事件,

因此你漏了这个部分:

Vue.component('button-counter', {
  template: '<button v-on:click="incrementCounter">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    incrementCounter: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})

实际上子组件调用父组件,也可以通过Prop实现:

使用 Prop 传递数据

组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,我们需要通过子组件的
props 选项。 子组件要显式地用 props 选项声明它期待获得的数据:

参见 使用-Prop-传递数据

具体代码我写了一下:

<div id="counter-event-example">
  <p>{{total}}</p>
  <button-counter :increment-total="incrementTotal"></button-counter>
  <button-counter :increment-total="incrementTotal"></button-counter>
</div>

Javascript:

    Vue.component('button-counter', {
      template: '<button @click="incrementTotal">{{counter}}</button>',
      props: {
        incrementTotal: {
          type: Function,
          required: true
        }
      },

      data: function () {
        return {
          counter: 0
        }
      }
    });

    new Vue({
      el: '#counter-event-example',
      data: {
        total: 0
      },

      methods: {
        incrementTotal: function () {
          this.total += 1;
        }
      }
    });
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题