vue组件通讯大全

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方法就会调用,控制台就会输出:image.png

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中的方法,控制台就会显示:image.png

这是兄弟组件通讯的方法,咱们也能够经过$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')

以上内容只是本人的学习总结,紧供参考。

相关文章
相关标签/搜索