【问题标题】:Call parent method with component用组件调用父方法
【发布时间】:2018-02-22 19:38:39
【问题描述】:

我有一个组件,想在 Vue.js 的父模板中添加一个运行方法的点击监听器。这可能吗?

<template>
    <custom-element @click="someMethod"></custom-element>
</template>

<script>
    export default {
        name: 'template',
        methods: {
            someMethod: function() {
                console.log(true);
        }
    }
</script>

【问题讨论】:

标签: javascript vue.js


【解决方案1】:

您可以将 $root like this 与 vanilla Vue 一起使用,但是,如果您将 nuxt 与 vue 一起使用,则该响应将不起作用。为什么?因为$root 本身就是nuxt。让我给你举个例子:

this.$root.$children[1].myRootMethod()
  • $root:正如我之前所说,这是nuxt。

  • $children[0]:这是 nuxtloading。

  • $children[1]:这是你的主要组件,在我的例子中,它是一个包含一些全局组件和一个全局 mixin 的基本布局。

  • $children[n]您应用中的其他组件。

希望对你有帮助。

【讨论】:

  • 这可行,但有点反模式。它降低了可读性。对于类似的情况(反模式)并且看起来更好的一个只是访问 $parent 来调用该方法。 this.$parent.parentMethod()
  • @ChaseChoi 不,这不起作用,因为我的代码就像一个绝对路径,它不依赖于子组件,因为结果总是相同的。
  • this.$parent.$options.methods.methodName();是唯一对我有用的东西吗...
  • 是的,如果您只有一个父组件而不是曾祖父或未知数量的父组件,这可能会起作用。
【解决方案2】:

依赖调用this.$parent 会隐藏依赖关系,并且在您使用创建longer child hierarchy 的组件库时会中断

首选方法是:

  1. 显式将方法作为属性传递到子组件(与传递数据道具相同)
  2. 将全局方法声明为 mixins

来自尼尔斯对Vue.js inheritance call parent method的回答:

  1. 传递道具(父子)

    var SomeComponentA = Vue.extend({
        methods: {
            someFunction: function () {
                // ClassA some stuff
            }
        }
    });
    
    var SomeComponentB = Vue.extend({
       props: [ 'someFunctionParent' ],
       methods: {
           someFunction: function () {
               // Do your stuff
               this.someFunctionParent();
           }
       }
    });
    

    在 SomeComponentA 的模板中:

    <some-component-b :someFunctionParent="someFunction"></some-component-b>
    
  2. 使用 Mixins

    如果这是您想在其他地方使用的常用功能,则使用 mixin 可能更符合习惯:

    var mixin = {
        methods: {
            someFunction: function() {
                // ...
            }
        }
    };
    var SomeComponentA = Vue.extend({
        mixins: [ mixin ],
        methods: {
        }
    });
    
    var SomeComponentB = Vue.extend({
       methods: {
           someFunctionExtended: function () {
               // Do your stuff
               this.someFunction();
           }
       }
    });
    

进一步阅读

【讨论】:

  • 1 号是 IMO 的好方法。我见过的最好的。我会为此使用 Vuex,但启用模式需要做很多工作。
【解决方案3】:

在当前vue版本中,这个解决方案:
Passing props (parent-child)

var SomeComponentA = Vue.extend({
    methods: {
        someFunction: function () {
            // ClassA some stuff
        }
    }
});

var SomeComponentB = Vue.extend({
   props: [ 'someFunctionParent' ],
   methods: {
       someFunction: function () {
           // Do your stuff
           this.someFunctionParent();
       }
   }
});

HTML 部分:

<some-component-b someFunctionParent="someFunction"></some-component-b>

基于this post,应该这样修改:

<some-component-b v-bind:someFunctionParent="someFunction"></some-component-b>

【讨论】:

    【解决方案4】:

    直接来自 Vue.js documentation:

    在 Vue 中,父子组件关系可以概括为 props down,events up。 parent 通过 props 向下传递数据给 child,child 通过 events 向 parent 发送消息...

    因此,当发生某些事情时,您需要从子组件中发出 click 事件,然后可以使用该事件来调用父模板中的方法。

    如果您不想从子组件显式发出事件(使用子组件中的this.$emit('click')),您也可以尝试使用native click event@click.native="someMethod"

    【讨论】:

      【解决方案5】:

      是的!

      可以从子级调用父级方法,非常简单。

      每个 Vue 组件都定义了属性$parent。然后,您可以从此属性调用父级中存在的任何方法。

      这是一个 JSFiddle:https://jsfiddle.net/50qt9ce3/1/

      <script src="https://unpkg.com/vue"></script>
      
      <template id="child-template">
          <span @click="someMethod">Click me!</span>
      </template>
      
      <div id="app">
        <child></child>
      </div>
      
      <script>
      Vue.component('child', {
        template: '#child-template',
        methods: {
          someMethod(){
              this.$parent.someMethod();
          }
          }
      });
      
      var app = new Vue({
          el: '#app',
        methods: {
          someMethod(){
              alert('parent');
          }
          }
      });
      </script>
      

      注意:虽然在构建断开连接的可重用组件时不建议这样做,但有时我们正在构建相关的不可重用组件,在这种情况下非常方便。

      【讨论】:

      • 这不再适合我,获取 this.$parent.myMethod 不是函数
      • @raklos 它仍然适用于目前 2.6.11 的最新版本 vue.js。如果它对您不起作用,则问题出在其他地方。我建议用您正在使用的代码提出另一个问题以寻求帮助。
      • @raklos 您可能在函数的“响应部分”中调用它。在这种情况下,以下问题可能会提供您正在寻找的内容:stackoverflow.com/questions/51382072/…
      • 对于那些得到“this.$parent.myMethod is not a function”错误的人尝试this.$parent.$parent.myMethodthis.$parent.$parent.$parent.myMethod等等。您的方法可能不在直接父级中,而是在组件层次结构中更高的位置。
      • 此解决方案非常不可靠,因为它依赖于组件层次结构。如果您从模板内的不同组件调用该方法,它将不起作用:&lt;template id="child-template"&gt; &lt;!-- will work with this.$parent --&gt; &lt;span @click="someMethod"&gt;Click me!&lt;/span&gt; &lt;custom-component&gt; &lt;!-- will work with this.$parent.$parent --&gt; &lt;span @click="someMethod"&gt;Click me!&lt;/span&gt; &lt;/custom-component&gt; &lt;/template&gt;(对不起,我无法在此处正确格式化代码)
      【解决方案6】:

      您可以通过props 将父方法向下传递给子组件,也可以让子组件发出自定义或原生事件。

      这里有一个Plunker 来演示这两种方法。

      【讨论】:

        猜你喜欢
        • 2020-09-11
        • 1970-01-01
        • 2020-10-20
        • 2021-05-02
        • 1970-01-01
        • 2022-07-07
        • 2023-01-08
        • 2017-08-04
        相关资源
        最近更新 更多