非父子组件的传值

我们可以把网页拆分成很多个部分

非父子组件的传值

首先是一个大的网页,然后上面是一个组件,左边也是一个组件,但是又可以拆分成2个组件,右边也是一个组件,但是也可以细分为3个组件

那么现在我想要父子组件传值可以通过:

父组件-子组件:通过props传值

子组件-父组件:通过事件触发传值

那么现在我想要第一层的组件和第三层的组件传值,如果用父子组件传值方法,那么就只能一层一层传,如果我现在想要右边的第三层组件和左边的第三层组件相互传值,也只能一层一层传递到第一层,然后再传递回来

这样做太过麻烦

那么我们可以使用 总线/Bus/发布订阅模式/观察者模式  来解决这个问题
非父子组件的传值

非父子组件的传值

现在想要实现的功能是当我点击Dell的时候,下面的Lee会变成Dell,点击Lee的时候,上面的Dell会变成Lee

非父子组件的传值

首先是在Vue的protptype上挂载了一个名字叫做bus的属性,Vue.prototype.bus = new Vue(),这个属性指向一个Vue的实例,只要以后调用new Vue()或者创建组件的时候每一个组件上都会有一个bus属性,

既然我想要一个子组件在被点击的时候,另一个子组件的内容能够随之改变,那么先在div上写一个监听函数,<div @click="handleClick">{{content}}</div>

现在我想要往另一个组件上传递自己的信息

handleClick: function() {
                    this.bus.$emit('change', this.content);
}

this.bus 指的就是实例上挂载的bus,bus又是Vue上的实例,那么我们就可以通过¥emit这个属性来触发事件,同时携带了我们的数据,this.content

那么对于其他的组件来说,就要去监听这个change,怎么监听能,我们可以使用mounted这个生命周期钩子,也就是这个组件被挂载的时候会执行的函数

mounted: function() {
                this.bus.$on('change', function(msg) {
                    content = msg;
                });
     }

当然在写到这里的时候,

非父子组件的传值

当你点击dell的时候会发现dell运行了两次

非父子组件的传值

这是因为在一个child组件去触发事件的时候,两个child组件都进行了事件的监听,所以两个child都会显示这个msg

那么现在,只要我把this.content = msg 就可以了

非父子组件的传值

点击完之后发现并没有什么改变,这是因为function(msg) {
                    this.content = msg;
                }

里面的this作用域发生了变化,

非父子组件的传值

这样就可以了,再点击dell下面的lee就变成了dell

非父子组件的传值

做完这些之后我们会发现控制台报错了

非父子组件的传值

这是因为子组件的content是从父组件传过来的,但是我们却强行改变了其内容

this_.content = msg;

所以要改成下面这样子:

非父子组件的传值

非父子组件的传值

非父子组件的传值

控制台也不会报错