A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 天树123 中级黑马   /  2020-1-16 15:07  /  1038 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

一、父子组件通信
1.props和$emit
props最常见的父子通信接口,但是props是单向数据流的形式:父级 prop 的更新会向下流动到子组件中,但是反过来则不行,此时需要借助vue提供的事件监听机制来完成子组件向父组件数据流动更新的功能。在子组件使用$emit定义监听事件名称,在父组件使用v-on监听该事件,在事件中改变父组件的状态。

2.parent和children或者$refs
1) $parent
$parent用来访问父组件实例,通常父组件都是唯一确定的。
2) $children
$children用来访问子组件实例,要知道一个组件的子组件可能是不唯一的,所以它的返回值是数组.
3) $refs
children的缺点是无法确定子组件的顺序,也不是响应式的。所以如果你确切的知道要访问的子组件建议使用refs。
refs需要使用ref属性在子组件上设置标识,然后通过this.refs.refName访问。
注意:ref属性作为组件属性时,访问的是根组件的实例;作为dom属性时,访问的是dom信息。

3.inheritAttrs和$attrs
1)inheritAttrs
这是@2.4新增的属性和接口。inheritAttrs属性控制子组件html属性上是否显示父组件的提供的属性。
从@2.4开始,在子组件默认添加inheritAttrs选项,并且默认为false,来隐藏这些属性,如果你期望这些属性是显示在根html元素上,你只需要将inheritAttrs的值指定为true。
2)$attrs
$attrs包含所有未在props中声明的父组件传递的属性。attrs简单的说就是props的加强版,因为当父组件提供props的属性十分多时,逐个在子组件显式的声明出来有时也是比较费事的。但是使用attrs就可以达到事半功倍的效果。$attrs还有个妙用就是将父组件所有未在props声明的属性通过v-bind传给自己的内部子组件(将父亲的属性通过自己传给自己的儿子),也就是说它可以作为隔代组件通信的桥梁。

二、兄弟组件通信
1.$root$root用来方位根实例属性
1)基本用法
个人认为 root的适用性是最好的,比如前面父子组件通信你使用了parent或者children,但是由于需求的改变等等不得已原因,它们的关系已经不是父子组件了,此时,通信机制就不能不重新建立了。但是如果你一开始就使用了$root作为通信机制,那么就不存在这样的麻烦了。
确切的说$root方法使用于任何情况的组件通信,包括父子组件、兄弟组件、隔代组件通信,可以形象的把它理解成为它们共同的祖先。
2)一个缺点
$root也有它的缺点,官网中也提到了,它只适合通用化(就是不用动态更新的意思)的场景,如果想建立随着改变动态更新的数据,建议使用vuex。
3)让它成为响应式
不过你尝试着给$root传递一个响应式的对象,当对象中的数据改变时,其余使用这个属性的地方也会跟着改变,也就是说它就是响应式的了。

2.eventBus
eventBus并不是vue官方的名称,它是使用vue实例的$emit接口建立全局的事件监听机制,很多人巧妙的使用它来组件通信,这种思想来源于Android事件发布/订阅轻量级框架eventBus。但是这并不是vue最优的通信机制。
1)创建
本质就是实例化一个空vue实例
2)使用
一般这种方式每个都会经历三个阶段,发起事件——>监听事件——>销毁事件。

三、隔代组件通信
1.provide和inject(依赖注入)
依赖注入是在provide选项中提供要共享的数据,在inject选项中使用共享的数据。它也是官方首推在不使用vuex时隔代组件通信方式。
1)使用
// 父级组件提供 'foo'
var Provider = {
  provide: {
    foo: 'bar'
  },
  // ...
}

// 任何后代组件注入 'foo'
var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}
需要知道的是,provide也可以是个函数,返回一个对象,更多细节可以参考详细的api文档 此外,它也和props一样可以设置默认值。
const Child = {
  inject: {
    foo: { default: 'foo' }
  }
}
// 或者
const Child = {
  inject: {
    foo: {
      from: 'bar',
      default: () => [1, 2, 3]
    }
  }
}

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马