Vue 组件间通讯

组件通讯

父组件 => 子组件
  • 属性 props
// 子组件
props: {
  msg: ''
}

// 父组件
<HelloWorld msg="welcome to Your Vue.js App"/>
  • 特性$attrs
// 子组件:并未在props中声明的特性
<p>{{$attrs.foo}}</p>

// 父组件
<Helloworld foo="foo">
  • 引用refs
// 父组件
<Helloworld ref="hw" />

mounted() {
  this.$refs.hw.xx = 'xxx'
}
  • 子元素$children
// 父组件
this.$children[0].xx = 'xxx';

子元素不保证顺序: 组件的加载是异步的

子组件 => 父组件
  • 自定义事件
// 子组件
this.$emit('add', good);

// 父组件
<Cart @add="cartAdd($event)"></Cart>

事件谁派发谁监听,即子组件派发事件add,同时也会监听事件add

兄弟组件 => 兄弟组件

通过共同的祖辈搭桥,$parent$root

// 兄弟组件1,监听当前实例上的自定义事件
this.$parent.$on('foo', handle)

// 兄弟组件2
this.$parent.$emit('foo');

祖先和后代之间

由于嵌套层数过多,传递props不切实际,vue提供了 provide/inject API 完成该任务

  • provide/inject: 能够实现祖先给后代传值
// ancestor   祖先
provide() {
  return { foo: 'foo' }
}

// descendant  后代
inject: ['foo']
任意两个组件之间
  • 事件总线:创建一个Bus类负责事件派发、监听和回调管理
class Bus{
  constructor() {
    this.callbacks = {}
  }
  $on(name, fn) {      // 事件监听
    this.callbacks[name] = this.callbacks[name] || [];
    this.callbacks[name].push(fn);
  }
  $emit(name, args) {
    if (this.callbacks[name]) {
      this.callbacks[name].forEach(cb => cb(args));
    }
  }
}

// main.js
vue.prototype.$bus = new Bus();
/*
Vue 本身已经实现了$on和$emit,因此new Bus()可以使用new Vue()代替
vue.prototype.$bus = new Vue();
*/

// child1, $on参数:监听事件, 函数
this.$bus.$on('foo', func)
// child2
this.$bus.$emit('foo');

实践中可以用Vue代替Bus,因为它已经实现了相应的功能

  • Vuex:创建唯一的全局数据管理者store,通过它管理数据并通知组件状态变更
全局添加混合 minix 方法
  • 实现后代组件传递数据给祖先元素
function $dispatch(enentName, data) {
  let parent = this.$parent;
  // 查找父元素
  parent.$emit(eventName, data);
  // 递归查找父元素
  parent = parent.$parent;
}
  • 实现子组件广播
function boardcast(eventName, data) {
  this.$children.forEach(child => {
    // 子元素触发$emit
    child.$emit(eventName, data);
    if (child.$children.length) {
       // 递归调用,通过call修改this指向 child
       boardcast.call(child, eventName, data);
    }
  });
}
发布了14 篇原创文章 · 获赞 0 · 访问量 141
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览