Vue組件間通信方式

前言
組件是 vue.js 最強大的功能之一,而組件實例的作用域是相互獨立的,這就意味著不同組件之間的數(shù)據(jù)無法相互引用,那么組件之間的通信顯得非常重要。
以下總結(jié)了 vue 組件間通信的幾種方式

方法一、props/$emit

1.父組件向子組件傳值

父組件通過 props 向下傳遞數(shù)據(jù)給子組件

2.子組件向父組件傳值

子組件傳遞數(shù)據(jù)給父組件是通過$emit觸發(fā)事件來做到的

//父組件
</template>
  <div class="comments">
    <!-- 精彩評論 -->
    <Hot-c
    :hotComments="comments.hotComments"  // 傳遞參數(shù),傳遞給子組件
    :moreHot="comments.moreHot"
    @toPraise="toPraise" // 傳遞事件,用于接受子組件數(shù)據(jù)
    />
  </div>
</template>

<script>
import HotC from './hotC/index.vue'
export default {
  name: 'App',
  data(){
    return{
      comments: { comments: '最新評論', hotComments: '精彩評論', moreHot: false}
    }
  },
  components:{
    HotC
  }
},
methods: {
    toPraise(msg) { // msg是子組件傳遞過來的
       this.comments.moreHot = true
       console.log(msg)   // liked
    }
  }
</script>
//子組件
<template>
  <div @click="click">
    {{ hotComments }}  // 直接使用
  </div>
</template>

<script>
export default {
  props:{
    hotComments:{           //這個就是父組件中子標(biāo)簽自定義名字
      type:String,
      required:true
    }
  },
  methods: {
    click() {
      this.$emit('toPraise', 'liked')  // 第一個參數(shù)為事件名,第二參數(shù)為要傳遞的值
    }
  }
}
</script>

方法二、emit / $on

事件總線
這種方法通過一個空的 Vue 實例作為中央事件總線(事件中心),用它來觸發(fā)事件和監(jiān)聽事件,巧妙而輕量地實現(xiàn)了任何組件間的通信,包括父子、兄弟、跨級。當(dāng)我們的項目比較大時,可以選擇更好的狀態(tài)管理解決方案 vuex。

// main.js
Vue.prototype.$eventBus = new Vue() // 可以放在vue原型上,也可以單獨建個js創(chuàng)建空的vue實例

//父組件
this.$eventBus.$emit(事件名,數(shù)據(jù))
//子組件
this.$eventBus.$on(事件名,data => {});

事件總線使用起來很方便,但是如果不正確的使用,將會是一場災(zāi)難,組件如果被循環(huán)得創(chuàng)建和銷毀,eventBus的我們監(jiān)聽需要手動移除,不然因為外部的引用會一直存在,在后期被反復(fù)觸發(fā),因此所有$eventBus的監(jiān)聽需要我們在組件銷毀時候?qū)⒈O(jiān)聽進行移除

beforDestory(){  
  this.$eventBus.$off ("事件名" )
}

方法三、provide/inject

provide / inject API 主要解決了跨級組件間的通信問題,不過它的使用場景,主要是子組件獲取上級組件的狀態(tài),跨級組件間建立了一種主動提供與依賴注入的關(guān)系。

// A.vue
export default {
  provide: {
    name: 'msg'
  }
}
// B.vue
export default {
  inject: ['name'],
  mounted () {
    console.log(this.name);  // msg
  }
}

需要注意的是:provide 和 inject 綁定并不是可響應(yīng)的。這是刻意為之的。然而,如果你傳入了一個可監(jiān)聽的對象,那么其對象的屬性還是可響應(yīng)的----vue 官方文檔

方法四、parent /children與 ref

ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實例
parent /children:訪問父 / 子實例

//父組件
</template>
  <div class="comments">
    <!-- 精彩評論 -->
    <Hot-c ref="hot"/>
  </div>
</template>

<script>
export default {
    mounted () {
      const comA = this.$refs.comA;
      console.log(comA.title);  // Vue.js
      comA.sayHello();  // 彈窗
    }
  }
</script>
//子組件
export default {
  data () {
    return {
      title: 'Vue.js'
    }
  },
  methods: {
    sayHello () {
      window.alert('Hello');
    }
  }
}

不過,這兩種方法的弊端是,無法在跨級或兄弟間通信

方法五、vuex

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容