首页 文章

Vue组件通信

提问于
浏览
24

我有两个Vue组件:

Vue.component('A', {});

Vue.component('B', {});

如何从组件B访问组件A?组件之间的通信如何工作?

5 回答

  • 2

    跨组件通信在Vue.js文档中没有得到太多关注,也没有很多教程涵盖这个主题 . 由于组件应该是隔离的,因此不应直接“访问”组件 . 这会将组件紧密地耦合在一起,这正是您想要阻止的 .

    Javascript有一个很好的沟通方法:事件 . Vue.js有一个内置的事件系统,主要用于父子通信 . From the docs

    虽然您可以直接访问Vue实例的子节点和父节点,但使用内置事件系统进行跨组件通信会更方便 . 它还使您的代码更少耦合,更易于维护 . Build 父子关系后,您可以使用每个组件的事件实例方法分派和触发事件 .

    他们的示例代码用于说明事件系统:

    var parent = new Vue({
      template: '<div><child></child></div>',
      created: function () {
        this.$on('child-created', function (child) {
          console.log('new child created: ')
          console.log(child)
        })
      },
      components: {
        child: {
          created: function () {
            this.$dispatch('child-created', this)
          }
        }
      }
    }).$mount()
    

    Dan Holloran最近在two pieces上发表了关于他的"struggle"的跨组件消息 . 如果您需要在没有父子关系的组件之间进行通信,这可能对您有所帮助 .

    我遇到的另一种方法(除了使用事件进行通信)是使用中央组件注册表,该注册表引用了公共API,并绑定了一个组件实例 . 注册表处理组件的请求并返回其公共API .

    在Vue.js的背景下,事件将由我选择的武器 .

  • 10

    除了pesla ' answer take a look at the guide' s State Management section under Building large scale appshttp://vuejs.org/guide/application.html#State_Management . 我在这里创建了一个jsfiddlehttps://jsfiddle.net/WarwickGrigg/xmpLg92c/ .

    这种技术也适用于组件:父子,兄弟 - 兄弟组件关系等 .

    var hub = {
      state: {
        message: 'Hello!'
      }
    }
    
    var vmA = new Vue({
        el: '#appA',
        data: {
          pState: {
            dA: "hello A" 
        },
        hubState: hub.state
      }
    })
    
    var vmB = new Vue({
        el: '#appB',
        data: {
          pState: {
            dB: "hello B"
        },
        hubState: hub.state
      }
    })
    
  • 0

    还可以通过在Vue应用程序中创建单个全局事件中心来 Build 组件之间的通信 . 像这样: -

    var bus = new Vue();

    现在,您可以创建自定义事件并从任何组件中侦听它们 .

    // A.vue
        // ...
        doThis() {
            // do the job
    
            bus.$emit('done-this');
        }
    
        // B.vue
        // ...
           method:{
                 foo: function()
              }
        created() {
            bus.$on('done-this', foo);
        }
    

    有关这方面的更多信息,请访问from official documentation. .

  • 6

    最佳做法是使用 propsevents .

    在线有很多例子,例如:

    我推荐一些有关该主题的阅读材料 .

    如果组件是兄弟姐妹并且没有父子关系,则可能值得检查应用程序的体系结构 .

    • AB 有父子关系吗?

    • 是否有一个组件 C 可能是 AB 的父组件?

    如果 ABC 的子项,请考虑使用道具和事件 . 另一种方法是使用 propssync ,这对表单数据很有用:

  • 27

    对于兄弟姐妹与兄弟姐妹的沟通,我发现使用父母作为事件总线使逻辑变得相当微不足道 . 使用 $root 作为事件总线意味着需要额外的代码来检查可能不是直接兄弟的组件的范围 . 使用 $parent 意味着可以控制发出的事件的范围 .

    以下示例适用于 TableHeader 组件 . 单击时,它会重新排序表中的数据,其他 Headers 不再处于活动状态,不应显示为此类,计算属性 cssClass 用于此目的 .

    export default {
        name: 'TableHeader',
        props: ['sort'],
        data() {
            return {
                direction: this.sort
            }
        },
        computed: {
            cssClass() {
                if (this.direction === 'none') return '';
                return (this.direction === 'descending') ? 'headerSortUp': 'headerSortDown';
            }
        },
        methods: {
            clickHeader(event) {
                this.direction = (this.direction === 'none' || this.direction === 'descending') ? 'ascending' : 'descending';
    
                //We use the parent as an event bus
                this.$parent.$emit('TableHeader:sortChanged', this);
            },
            sortChanged(element) {
                //Dont reset if this is the emitter         
                if (this === element) return; 
    
                this.direction = 'none';
            }
        },      
        created() {
            this.$parent.$on('TableHeader:sortChanged', this.sortChanged);
        },
        beforeDestroy: function () {
            this.$parent.$off('TableHeader:sortChanged', this.sortChanged)
        }
    }
    

相关问题