【问题标题】:Vue.js 2 - How to $emit event from one application/instance Vue to an other?Vue.js 2 - 如何将事件从一个应用程序/实例 Vue 发送到另一个?
【发布时间】:2017-08-07 21:56:21
【问题描述】:

我使用带有单个文件组件的 webpack。

我的菜单标题中有 1 个 Vue 实例来显示购物车购物下拉菜单:

import Vue from 'vue';
import App from './AppShoppingCart.vue';

new Vue({
    el: '#shoppingCartApp',
    template: '<App/>',
    components: {App}
});

我在同一页面(包含产品的目录)中有另一个 Vue 实例:

import Vue from 'vue';
import App from './AppCatalog.vue';

new Vue({
    el: '#catalogApp',
    template: '<App/>',
    components: {App}
});

我想将一个事件从一个实例发送到另一个实例: 当目录发生变化时,我想在 ShoppingCart 中调用一个函数。

我测试eventHub

import Vue from 'vue';

var eventHub = new Vue();
export default eventHub; 

所以我在每个实例上导入事件:

import eventHub from './events/eventHub';

在目录中:

eventHub.$emit( "actproductslist-changed" );

在购物车中:

eventHub.$on('actproductslist-changed', function(){ alert('AppShoppingCart') } );

但这行不通。仅当 $on 和 $emit 在同一 Vue 实例中时才有效。

我认为 webpack 创建了 2 个模块,我无法在我的 2 个实例之间共享变量。

任何人都知道使用 webpack 拥有多个实例的全局变量?

【问题讨论】:

    标签: vue.js vuejs2


    【解决方案1】:

    此设置有效,其中main.js 是您的入口点。

    bus.js

    import Vue from "vue"
    
    const bus = new Vue();
    export default bus;
    

    ma​​in.js

    import Vue from 'vue'
    import App from './App.vue'
    import App2 from './App2.vue'
    
    new Vue({
      el: '#app',
      render: h => h(App)
    })
    
    new Vue({
      el:"#app2",
      render: h => h(App2)
    })
    

    App.vue

    <template>
      <button @click="sendMessage">Send Message</button>
    </template>
    
    <script>
      import Vue from "vue"
      import bus from "./bus"
    
      export default {
        methods:{
          sendMessage(){
            bus.$emit("testing")
          }
        }    
      }
    </script>
    

    App2.vue

    <template></template>
    
    <script>
      import Vue from "vue"
      import bus from "./bus"
    
      export default {
        mounted(){
            bus.$on("testing", ()=> alert("message received"));
        }
      }
    </script>
    

    发表评论编辑

    要跨入口点进行通信,您可以在窗口上公开bus Vue。

    webpack.config.js

      entry: {
        "main": './src/main.js', 
        "main2": './src/main2.js'
      },
      output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',
        filename: '[name].js'
      },
    

    bus.js

    import Vue from "vue"
    
    window.bus = new Vue();
    

    ma​​in.js

    import Vue from 'vue'
    import App from './App.vue'
    
    new Vue({
      el: '#app',
      render: h => h(App)
    })
    

    ma​​in2.js

    import Vue from 'vue'
    import App2 from './App2.vue'
    import bus from "./bus"
    
    new Vue({
      el:"#app2",
      render: h => h(App2)
    })
    

    App.vue

    <template>
      <button @click="sendMessage">Send Message</button>
    </template>
    
    <script>
      import Vue from "vue"
    
      export default {
        methods:{
          sendMessage(){
            if (bus)
              bus.$emit("testing")
          }
        }    
      }
    </script>
    

    App2.vue

    <template></template>
    
    <script>
      import Vue from "vue"
    
      export default {
        mounted(){
            bus.$on("testing", ()=> alert("message received"));
        }
      }
    </script>
    

    这里请注意,由于bus 仅在main2.js 中导入,因此对于可能不存在的情况(因为它仅在main2.js 中导入),您需要注意在App.vue 中使用它。

    【讨论】:

    • 你是对的。但就我而言,我有 2 个 main.js,因为一个用于每个页面(购物车购物下拉菜单),另一个仅用于目录页面。所以我有 2 个输入/输出文件。在 shoppingCart.js 中有一个 if( #catalogApp is present in html ) => 也实例化 catalogVue 似乎很奇怪。你怎么看 ?我有一个 javascript 解决方案(在 div #shoppingCartEventHub 上有 addEventListener),但我更喜欢 Vue 解决方案。
    • @vuefan 是的,我不确定什么可以让您跨入口点进行通信。当我有时间时,我将不得不玩弄它。
    • @vuefan 已更新。将bus 暴露在窗口上可以让您在它们之间进行通信。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2017-01-30
    • 1970-01-01
    相关资源
    最近更新 更多