幾種常見的Vue元件間的傳參方式

魏晨歐尼醬鴨發表於2018-12-12

Vue父子元件通訊的方法其實有很多,本文只是做一個總結,說說他們的優缺點,具體如何使用相關文件和網上大神已經總結的很多裡,這裡就不再說明。

1.Vuex

介紹

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態, 並以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也整合到 Vue 的官方除錯工具 devtools extension, 提供了諸如零配置的 time-travel 除錯、狀態快照匯入匯出等高階除錯功能。

vuex是我平時專案裡經常用的工具之一,相信大家在專案中肯定也經常會使用它

使用方法

官網傳送門

優缺點

  • 優點
    • 解決了多層元件之間繁瑣的事件傳播。
    • 解決了多元件依賴統同一狀態的問題。
    • 單向資料流
    • 為Vue量身定做,學習成本不高
  • 缺點
    • 不能做資料持久化,重新整理頁面就要重製,要做資料持久化可以考慮使用localstorage。
    • 增加額外的程式碼體積,簡單的業務場景不建議使用。

2.EventBus

介紹

通過共享一個vue例項,使用該例項的$on以及$emit實現資料傳遞。

使用方法

下面是簡單的使用方法

// bus.js
import Vue from 'vue'
export default new Vue({})

// component-a.js
import bus from './bus.js'
export default {
  created () {
    bus.$on('event-name', (preload) => {
      // ...
    })
  }
}

// component-b.js
import bus from './bus.js'
export default {
  created () {
    bus.$emit('event-name', preload)
  }
}
複製程式碼

優缺點

  • 優點
    • 解決了多層元件之間繁瑣的事件傳播。
    • 使用原理十分簡單,程式碼量少。
  • 缺點
    • 由於是都使用一個Vue例項,所以容易出現重複觸發的情景,例如:
      1. 多人開發時,A、B兩個人定義了同一個事件名。
      2. 兩個頁面都定義了同一個事件名,並且沒有用$off銷燬(常出現在路由切換時)。
      3. 在for出來的元件裡註冊。
    • 專案一大用這種方式管理事件會十分混亂,這時候建議用vuex。

3.props和$emit/$on

介紹

最基本的父元件給子元件傳遞資料方式,將我們自定義的屬性傳給子元件,子元件通過$emit方法,觸發父元件v-on的事件,從而實現子元件觸發父元件方法

使用方法

props使用傳送門

$emit/$on使用傳送門

優缺點

  • 優點

    • 使用最為簡單,也是父子元件傳遞最常見的方法。
    • Vue為給props提供了型別檢查支援。
    • $emit不會修改到別的元件的同名事件,因為他只能觸發父級的事件,這裡和event-bus不同
  • 缺點

    • 單一元件層級一深需要逐層傳遞,會有很多不必要的程式碼量。
    • 不能解決了多元件依賴統同一狀態的問題。

Tips

$attrs/$listeners可以將父元件的props和事件監聽器繼承給子元素,在子元件可以呼叫到父元件的事件和props

$attrs使用傳送門

$listeners使用傳送門

4.provide/inject

介紹

在父元件上通過provide提供給後代元件的資料/方法,在後代元件上通過inject來接收被注入的資料/方法。

使用方法

官方傳送門

優缺點

  • 優點
    • 不用像props一層層傳遞,可以跨層級傳遞。
  • 缺點
    • 用這種方式傳遞的屬性是非響應式的,所以儘可能來傳遞一些靜態屬性。
    • 引用官網的話是它將你的應用以目前的元件組織方式耦合了起來,使重構變得更加困難。,我對這句話的理解是用了provide/inject你就要遵循它的元件組織方式,在專案的重構時如果要破壞這個組織方式會有額外的開發成本,其實event-bus也有這個問題。

5.slot

介紹

你可以在元件的html模版裡新增自定義內容,這個內容可以是任何程式碼模版,就像:

<navigation-link url="/profile">
  <!-- 新增一個 Font Awesome 圖示 -->
  <span class="fa fa-user"></span>
  Your Profile
</navigation-link>
複製程式碼

父元件模板的所有東西都會在父級作用域內編譯;子元件模板的所有東西都會在子級作用域內編譯。

你也可以通過slot-scope屬性來實現從子元件將一些資訊傳遞給父元件,注意這個屬性是vue2.1.0+新增的。

使用方法

官方傳送門

優缺點

  • 優點
    • 可以在父元件裡自定義插入到子元件裡的內容,雖然其他屬性也可以,但是我覺得slot更傾向於自定義的條件是來自於父容器中。
    • 複用性好,適合做元件開發。
  • 缺點
    • 和props一樣不支援跨層級傳遞。

6.$parent/$children

介紹

通過$parent/$children可以拿到父子元件的例項,從而呼叫例項裡的方法,實現父子元件通訊。並不推薦這種做法。

使用方法

通過this.$parent或者this.$children拿到父或子元件例項。官方傳送門

優缺點

  • 優點
    • 可以拿到父子元件例項,從而擁有例項裡的所有屬性。
  • 缺點
    • 用這種方法寫出來的元件十分難維護,因為你並不知道資料的來源是哪裡,有悖於單向資料流的原則
    • this.$children拿到的是一個陣列,你並不能很準確的找到你要找的子元件的位置,尤其是子元件多的時候。

相關文章