vue组件通讯方式不少同窗会说我知道,这个简单,props传值,$emit回传,再不行就vuex。但实际上vue组件通讯远远不止这些,并非层级一多就要用vuex,一个项目就要隔多级传几个静态参数,你说我用vuex,我想这就是杀鸡用了宰牛刀,今天就来讲一下具体有多少种方式,而且如何应用。vue
组件通讯经常使用方式vuex
一、props/$emit。
二、event。
三、vuex。
自定义事件
1.边界状况api
四、 $parent。
五、 $root。
六、 $children。
七、 $refs。
八、 provide/inject。
2.非prop特性数组
九、 $attrs。
十、 $listeners。
1.props/$emit
props传值很是简单,这个是最最经常使用的,我简单写下例子。app
父组件给子组件传值dom
// parent 组件 <Parent msg="Welcome to vue props"/> // child里面经过props获取msg props: { msg: String }
子组件传值给父组件,使用$emitide
// child里面调用$emit, 第一个参数是方法名,后面都是参数 this.$emit('add', good) // parent,$emit会触发父组件add方法 <Parent @add="parentAdd($event)" />
2.event事件总线
前面说到的props和/$emit父子组件通讯,他们存在引入与被引入的关系,若是不存在这种关系咱们该怎么办呢?
这时咱们经常会用到事件总线或者vuex的方式。学习
首先在main.js文件中经过vue原型属性初始化EventBus,
这种方式初始化的是一个全局事件总线。ui
import Vue from 'vue' import App from './App.vue' // 事件总线 Vue.prototype.$bus = new Vue() new Vue({ render: h => h(App), }).$mount('#app')
在组件1中发送信息this
// 利用事件总线发送事件 this.$bus.$emit('event-from-component1', 'some msg from component1')
在组件2中监听接受信息
this.$bus.$on('event-from-component1', msg => { console.log('component2:', msg); });
这时只要在组件1中触发$bus.$emit的方法,组件2中$bus.$on方法就会调用,控制台就会输出:
3.vuex
建立惟一的全局数据管理者store,经过它管理数据并通知组件状态变动。
vuex的强大这里就不赘述了,vuex内容比较多也不是本文的主题,这里就不细讲了,不熟悉的同窗先去看下官网:https://vuex.vuejs.org/zh/guide
4.$parent
兄弟组件直接能够经过共同的祖先搭桥联通,$parent和$root均可以作到。
// brother1中发出方法 this.$parent.$emit('event-from-brother1', 'some msg from brother1')` // brother2中接收方法 this.$parent.$on('event-from-brother1', msg => { console.log('brother2:', msg); });
这时触发brother1中的方法,控制台就会显示:
这是兄弟组件通讯的方法,咱们也能够经过$parent从子组件调用父组件的方法。
// parent里面methods定义了一个方法 methods: { fatherMethod() { console.log('我是你爹'); } } // children子组件里面调用父组件方法 this.$parent.fatherMethod()
当$parent.fatherMethod()方法在子组件被调用控制台便会打出:我是你爹
5.$root
$root和上面parent相似,这里就不赘述,具体请移步官网。
6.$children
父组件能够经过$children访问子组件实现父子通讯,可是父组件可能含有多个子组件,因此要区分开
this.$children[index].xx = 'xxx'
可是有一点须要注意$children实际上不能保证子元素的顺序,也不是响应式的。
由于$children
是根据你页面加载组件的顺序去肯定子组件在 $children
数组中的顺序。
若是A组件在B组件先加载,那么A组件的下标就是0,B组件的下标就是1。
若是有动态组件很容易出错,因此咱们并不建议使用。
然而咱们经常使用的$refs
就能够解决这个问题。
7.$refs
回去节点引用,也就是获取dom
// dom中引入 <div ref="tx" /> // 获取上面div的dom从而操做 this.$refs.tx
在父组件中经过ref调用子组件的方法,这里就不会有$children的顺序问题了,由于ref是一一对应的。
// 父组件 <Child2 ref="child2" msg="some message"></Child2> // 子组件 methods: { sendToChild1() { console.log('我是父组件使用ref调用的方法') } }, // 在父组件中调用子组件方法sendToChild1 `this.$refs.child2.sendToChild1()`
8.provide/inject
可以很好的跨层级通讯。官网也作比较详细的说明:https://cn.vuejs.org/v2/api/#...。
这个方法其实也挺好用的,可是不少同窗并无用过,可能都不是很清楚。
下面咱们来具体说一下:
// 祖辈组件中提供了一个变量,这时咱们使用provide方法注入 provide() { return { father: 'father' } }, // 这时咱们须要在某个后代元素中获取这个father变量 // 注入以后咱们就能够在该后代组件中使用变量father了 inject: ['father'] // inject另一种写法 // 这时咱们须要对变量重命名,同时能够设置默认值 inject: { bar1: { from: 'father', default: 'barrrrrrrr' } },
咱们也能够把注入值放入咱们该后代元素的data中去使用,provide/inject基本用法就是这样的。
9.$attrs
$attrs包含了父做用域中不做为 prop 被识别 (且获取) 的特性绑定 ( class 和 style 除外)。
当一个组件没有 声明任何 prop 时,这里会包含全部父做用域的绑定 ( class 和 style 除外),而且能够经过 v- bind="$attrs" 传入内部组件——在建立高级别的组件时很是有用。
// 爷爷组件中给父亲组件注入信息 <Parent msg="msg" /> // 父亲组件,咱们须要在父亲组件中绑定$attr以便于孙子组件获取信息 <Children v-bind="$attrs" /> // 孙子组件:在props中没有声明msg,这时子组件依然可以收到信息 <div> {{$attrs.msg}}</div>
这时孙子组件就能够获取msg的信息了,这里其实都是跨层级通讯的。
10.$listeners
若是咱们须要从孙子组件调用爷爷组件的方法,实现跨层级通讯的话,可使用到$listeners。
// 爷爷组件 <Parent msg="msg" @foo="onFoo"/> // 爷爷组件methods设置方法 onFoo() { console.log('msg from Children'); } // 父亲组件,绑定$listeners <Children v-bind="$attrs" v-on="$listeners" /> // 孙子组件:调用foo方法 this.$emit('foo')
以上内容只是本人的学习总结,紧供参考。