【问题标题】:Vue.js - How to call method from another componentVue.js - 如何从另一个组件调用方法
【发布时间】:2017-08-16 20:22:59
【问题描述】:

我正在使用 Vue.Js v2。提交后我想在component2->c2method中调用component1->c1method来重新加载数据。

Vue.component('component1', {
  methods: {
    c1method: function(){
     alert('this is c1method')
    },
  }
})
Vue.component('component2', {
  methods: {
    c2method: function(){
     component('component1').c1method()//like this
    },
  }
})

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-component


    【解决方案1】:

    对于非父子关系,则与此相同。从任何其他组件调用一个方法,显然是组件的任何方法。只需将$on 函数添加到$root 实例并调用任何其他访问$root 和调用$emit 函数的组件。

    在第一个组件上

    …… 挂载(){ this.$root.$on('component1', () => { // 你的代码在这里 this.c1method() } }

    在第二个组件中调用$root中的$emit函数

    ... c2方法:函数(){ this.$root.$emit('component1') //像这样 },

    它更像是一个套接字。参考这里

    https://stackoverflow.com/a/50343039/6090215

    【讨论】:

    • 基本上你可以使用$on函数将事件添加到vue实例并命名事件以及它触发的函数,你可以使用$emit函数和调用事件名称来触发该事件.我所做的是使用 $root 在 Vue 的根实例上创建一个事件总线,现在我可以从任何子实例触发该事件。更多信息在这里 => vuejs.org/v2/api/#Instance-Methods-Events
    • 第一个代码段在倒数第二个括号中缺少“)”
    • @MirAymanAli 它只在mounted() 中有效吗?
    • @YongPin 我们可能正在做的是将函数添加到 vue 全局事件总线。安装是最安全的选择。但是如果您想动态附加它,请谨慎行事,因为其他组件不会知道何时附加事件。此解决方案仅在两个组件位于同一视口上时才有效,这意味着您正在同时查看两个组件。
    【解决方案2】:
    // Component A
    Vue.component('A', {
        created() {
            this.$root.$refs.A = this;
        },
        methods: {
            foo: function() {
                alert('this is A.foo');
            }
        }
    });
    
    // Component B
    Vue.component('B', {
        methods: {
            bar: function() {
                this.$root.$refs.A.foo();
            }
        }
    });
    

    【讨论】:

    • 非常好的解决方案
    • 我目前正在学习 Vue.js,这个解决方案解决了我的问题!谢谢!
    • 你的代码应该被标记为答案,太棒了!
    • 绝妙的解决方案!
    • 这让我的屏幕变黑了。我正在使用 Vue3。
    【解决方案3】:

    不需要千篇一律的解决方案。
    在 vuejs 中,我们可以创建可以全局监听的事件。
    有了这个特性,每当我们想要调用我们心爱的函数时,我们就发出这个事件。
    现在,我们只是一直从组件中监听这个事件。每当这个全局事件发生时,我们就可以执行我们想要调用的方法。

    这很简单:

    1. 你去main.js,在创建vue实例之前,这样写:
    export const eventBus = new Vue(); // added line
    
    
    new Vue({
        ...
        ...
        ...
        render: h => h(App)
    }).$mount('#app');
    
    
    
    1. 我们想在任何地方触发目标函数,我们不触发它,我们只是发出这个事件:
    eventBus.$emit('fireMethod');
    
    1. 现在在我们的具有目标函数的组件中,我们总是监听这个事件:
    created() {
        eventBus.$on('fireMethod', () => {
                this.myBelovedMethod();
        })
    }
    

    不要忘记在顶部导入 eventBus。

    import {eventBus} from "path/to/main.js";
    

    就是这样,几行代码,没有 hacky,所有 vuejs 的力量。

    【讨论】:

    • 我猜最后的导入路径应该是 main.js。
    • 好答案!但是,我同意我们应该将最后一段代码从“path/to/app.js”更改为“path/to/main.js”,并明确说明在步骤之前在操作的所有组件的顶部导入 eventBus 2 和 3。
    【解决方案4】:

    文档解决了这种情况

    https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication

    如果您的组件具有相同的父级,则可以发出父级侦听的事件。然后使用ref 属性集,您可以从父级调用c1method

    https://vuejs.org/v2/guide/components.html#Child-Component-Refs

    【讨论】:

      【解决方案5】:

      试试这个。

      <template>
       ...
       <component1 ref='componentOne'>
      ...
      </template>
      <script>
        Vue.component('component2', {
          methods: {
           c2method: function(){
             this.$refs.componentOne.c1method();
           }
         }
        });
      </script>
      

      【讨论】:

        【解决方案6】:

        如果有人在 Vue.js v3 中寻找解决方案:

        https://v3.vuejs.org/guide/migration/events-api.html#event-bus

        https://github.com/developit/mitt#install

            import mitt from 'mitt'
            
            const emitter = mitt()
            
            // listen to an event
            emitter.on('foo', e => console.log('foo', e) )
            
            // listen to all events
            emitter.on('*', (type, e) => console.log(type, e) )
            
            // fire an event
            emitter.emit('foo', { a: 'b' })
            
            // clearing all events
            emitter.all.clear()
        

        【讨论】:

          猜你喜欢
          • 2016-05-22
          • 2020-04-05
          • 2018-06-14
          • 2019-06-16
          • 2021-06-15
          • 2017-05-19
          • 2016-07-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多