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')

以上內容只是本人的學習總結,緊供參考。

相關文章
相關標籤/搜索