思路
- 首先可以让所有组件访问到
尝试1:是不是可以往window身上放一个x?widnow.x=123;虽然其他组件的确可以访问到,但在使用框架时很少去往window身上放东西,这的确不太好。放弃。
尝试2:所有的组件都能看的见,那就是VueComponent的实例对象都能看的见,那么我们可以往VueComponent构造函数的原型对象上添加x,VueComponent.prototype.x=123;
但是需要注意的是,我们并不能直接拿到VueComponent这个构造函数,还有最重要的一点,通过源码得知,其实每次组件创建都是通过一个新的VueComponent构造函数,那么他们的原型对象也不是一个,所以此路不通。
尝试3:除了我们可以往VueComponent的原型对象上放,还可以往唯一的Vue构造函数的原型对象上放。
Vue.prototype.x=123;
- 实现让x有图中的方法
尝试1:很明显$on这些方法组件实例的身上就有,那么我们可以让x是一个组件的实例,换个方法拿VueComponent构造函数
const Demo = Vue.extend({});
const demo = new Demo();
Vue.prototype.x = demo;
尝试2:$on这些方法组件实例身上有的根本原因是在于这些方法在Vue构造函数的原型对象上面。所以如果x的值是Vue的实例对象也是可以的。在main.js中刚好有new这个实例对象,所以我们尝试写一下
const vm = new Vue({
render: h => h(App),
}).$mount('#app');
Vue.prototype.x = demo;
执行代码发现报错,因为去定义x的时候,app已经挂载完成,子组件在mounted中给x绑定事件,就已经晚了。
尝试3:使用钩子
new Vue({
render: h => h(App),
beforeCreate(){
//this本来就是这个vue实例,况且这里写vm也不行,妙
Vue.prototype.x = this;
}
}).$mount('#app');
备注:x一般叫$bus,因为bus刚好有总线的含义。
知识点
- 一种组件间的通信方式,适用于任意组件间通信。
- 安装全局事件总线
new Vue({
....
Vue.prototype.$bus = this;
.....
})
- 使用事件总线
- 如果A组件想接受数据,那么就给$bus定义一个自定义事件,并把回调写在A中。
{ .... mounted(){ this.$bus.$on('peiqi',getData) } methods:{ getData(data){.....} } .... }
- 提供数据
this.$bus.emit('peiqi',666)
- 最好在beforeDestroy钩子中,用$off解绑当前组件所用到的事件。
网友评论