【问题标题】:Call parent methods from child components (Vue.js)从子组件调用父方法(Vue.js)
【发布时间】:2020-09-11 20:39:18
【问题描述】:

我正在做一个项目,我需要从子组件调用父方法。这在 Vue.js 中如何实现?

【问题讨论】:

  • this.$emit()
  • 您能否提供更多详细信息。链接也许
  • 您使用this.$emit("myEvent") 在您的孩子身上发出一个事件。在您的父组件中,假设孩子的名字是myComponent,所以您需要使用<myComponent @myEvent="putYourParentMethodHere"></myComponent> 来收听该事件,这就是它的工作原理

标签: javascript node.js vue.js vuejs2 vue-component


【解决方案1】:

当您想触发父组件中的方法时,您应该在子组件中使用this.$emit('myEvent')

然后在父组件的模板中找到你的子组件,并在其上添加一个事件捕获器,如下所示:

<template>
  <your-child-component @myEvent="myMethod"/>
</template>

如果你想为你的方法添加参数,你可以像这样向你的发射添加第二个参数:

this.$emit("myEvent", "My parameter")

只要您调用的方法有参数,您就不必更改事件“catcher”中的任何内容。

【讨论】:

  • 注意事件名称的大小写。至少在 vuejs3 中,组件调用不支持混合大小写,因此: 应改为:
【解决方案2】:

也许工作示例会更清楚。

https://m-vue-leaflet.netlify.app/

代码-https://github.com/manojkmishra/vue-leaflet-mapping

所以这里如果你看到 components 文件夹中有 3 个 vue 文件。 Brew.vue 是 BrewList.vue 子组件的父组件。

Brew.vue- 父组件

BrewList.vue - 子组件

子组件 BrewList.vue 正在使用 emit 将 mouse-over-brew 和 mouse-leave-brew 值发送到父 Brew.vue。此外,如果您有兴趣,Brew.vue 父级正在将 brew prop 发送到 BrewList.vue 子级。

根据文档- https://vuejs.org/v2/guide/components.html#Listening-to-Child-Components-Events

【讨论】:

    【解决方案3】:

    2021 年 12 月更新:

    它适用于 $emit。父组件中@callTest的名称必须与$emit('callTest')的名称相同在子组件中。

    父组件

    <template>
      <Child
        @callTest="test" // Assign 'test' method to @callTest
      />
    </template>
    
    <script>
    import Child from "../components/Child.vue";
    import { defineComponent } from "vue";
    
    export default defineComponent({
      name: "Parent",
    
      components: {
        Child,
      },
    
      methods: {
        test() {
          alert("Test");
        },
      }
    });
    </script>
    

    子组件

    <template>
      <button @click="$emit('callTest')">Click Me</button>
    </template>
    
    <script>
    import { defineComponent } from "vue";
        
    export default defineComponent({
      name: "Child",
    });
    </script>
    

    同样,@callTest 在父组件中的名称必须与 $emit('callTest') 在子组件中。


    如果您在 script 部分使用 $emit,则需要 this 不同于 template 部分。

    子组件

    <template>
      <button @click="message">Click Me</button>
    </template>
    
    <script>
    import { defineComponent } from "vue";
        
    export default defineComponent({
      name: "Child",
      methods: {
        message() {
          this.$emit('callTest') // 'this' is needed.
        }
      }
    });
    </script>
    

    如果test方法有2 parameters,你需要调用test方法和2 arguments 在子组件中,如下所示。

    父组件

    <template>
      <Child
        @callTest="test" // Assign 'test' method to @callTest
      />
    </template>
    
    <script>
    import Child from "../components/Child.vue";
    import { defineComponent } from "vue";
    
    export default defineComponent({
      name: "Parent",
    
      omponents: {
        Child,
      },
            
      methods: {
        test(num1, num2) { // 'test' method has 2 parameters.
          alert(num1 + num2);
        },
      }
    });
    </script>
    

    子组件

    <template>       // Call 'test' method with 2 arguments.                          
      <button @click="$emit('callTest', 3, 5)">Click Me</button>
    </template>
    
    <script>
    import { defineComponent } from "vue";
            
    export default defineComponent({
      name: "Child",
    });
    </script>
    

    【讨论】:

      【解决方案4】:

      理想情况下,这是正确的做法: https://vuejs.org/v2/guide/components.html#Listening-to-Child-Components-Events

      另一方面,我相信你的场景(我试图假设它不是很清楚),你可以使用 this.$parent.methodName。

      请记住,第二个建议不太干净。它应该在需要时使用。

      【讨论】:

        【解决方案5】:

        所以基本上,有两种方法可以回答您的问题

        1. 使用$emit,语法为@

        2. 传递function as props,语法为和你的例子一样

        如果您基于 Vue 文档和许多其他 Vue 教程,您会发现它们鼓励人们使用 $emit 事件 而不是 传递 函数作为道具(你使用的方式)。您可以在此处阅读文档。

        https://vuejs.org/v2/guide/components-custom-events.html https://vuejs.org/v2/guide/components.html#Emitting-a-Value-With-an-Event https://code.tutsplus.com/tutorials/design-patterns-for-communication-between-vuejs-component--cms-32354 vue, emitting vs passing function as props

        原因是 Vue 的哲学是向下传递道具,向上发射事件。使用 $emit 将有助于将触发的函数标记为 Vue 事件,因此您可以使用全局事件监听器。这也可以帮助您区分数据流逻辑事件流逻辑

        不过,用function作为props并没有错,实际上也可以用它来达到同样的效果。在我的偏好中,我在编写具有默认功能的组件时使用第二种方式,并且该功能仅在父母传递另一个时才被覆盖。这将帮助我避免多次重写默认函数。

        对于其余的情况,我将使用第一种方式 $emit。

        【讨论】:

          【解决方案6】:

          家长

          <complited v-on:passData="fromChild" />
          
            methods: {
                fromChild(data) {
                  if (data.methodCall) return this[data.methodCall]();
                }
          
                aFunction() {
                  alert('function: a');
                }
          
                bFunction() {
                  alert('function: b');
                }
            }
          

          儿童

          <template>
             <div>
              <button @click="parentCall()">Call Parent Function
              </button>
             </div>
            </template>
            methods: {
                parentCall() {
                  this.$emit("passData", {methodCall: 'aFunction' });
                }
            }
          

          【讨论】:

            【解决方案7】:

            我用 props 做到了这一点。通过 props 将父方法传递给子组件。并从子组件访问。

            在子组件中

            props: ["lesson","fetchLessons"],
            

            并在子组件中访问这样的道具

            this.fetchLessons();
            

            父组件

            <InstructorLesson  v-for="(lesson,index) in getFechedLessons" :lesson="lesson" :fetchLessons = "fetchLessons" v-bind:key="index"/>
            

            【讨论】:

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