高級 Vue 組件模式 (2)

02 編寫複合組件

目標

咱們須要實現的需求是可以使使用者經過 <toggle> 組件動態地改變包含在它內部的內容。vue

熟悉 vue 的童鞋可能立刻會想到不一樣的解決方案,好比使用 slot 並配合 v-if,咱們這裏採用另一種方法,利用 vue 提供的 provide/inject 屬性按照複合組件的思想來實現。git

這裏簡單介紹下 provide/inject 的功能,它容許某個父組件向子組件注入一個依賴項(這裏的父子關係能夠跨域多個層級,也就是祖先與後代),若是咱們在其餘 mvvm 框架對比來看的話,你能夠發現其餘框架也具備相同的特性,好比:angularjs

  • angularjs: directive 中的 require 屬性來聲明注入邏輯
  • Angular: 依賴注入中組件級別的注入器
  • React: context 上下文對象

想進一步瞭解的話,能夠參考官方文檔github

實現

在 vue 中,這裏咱們會分別實現三個組件,依次爲:api

  • toggle-button: 表明開關,用來渲染父組件的開關狀態
  • toggle-on: 根據父組件 toggle 的開關狀態,渲染當狀態爲時的內容
  • toggle-off: 根據父組件 toggle 的開關狀態,渲染當狀態爲時的內容

在上一篇文章中,咱們已經實現了 toggle 組件,這裏咱們要作一些更改。首先,須要使用 provide 屬性增長一個提供依賴的邏輯,以下:跨域

provide() {
    return {
      toggleComp: {
        status: this.status,
        toggle: this.toggle
      }
    }
}

這裏的 status 是該組件 data 中的聲明的一個可監聽對象,這個對象包含一個 on 屬性來表明組件的開關狀態,而 toggle 則是 methods 中的一個組件方法。框架

關於爲何這裏不直接使用 on 屬性來表明開關狀態,而使用一個可監聽對象,是由於 provideinject 綁定並非可響應的,同時官方文檔也指出,這是刻意而爲,因此爲了享受到 vue 響應性帶來的便利性,咱們這裏傳入 status 這個可監聽對象。mvvm

對於其餘三個組件,其內部實現邏輯十分簡單,相信讀者經過參考在線代碼實例立刻就能看懂,這裏只提一下關於 inject 聲明注入依賴的邏輯,以下:ide

inject: { toggleComp: "toggleComp" }

這裏的 "toggleComp" 與以前的 provide 對象中聲明的 key 值所對應,而 inject 對象的 key 值當前組件注入依賴項的變量名稱,以後,子組件便可以經過 this.toggleComp 來訪問父組件的屬性與方法。ui

成果

經過複合組件的方式,咱們將 toggle 組件劃分爲了三個更小的、職責更加單一的子組件。同時因爲 toggle-ontoggle-off 都使用 slot 來動態地注入組件調用者在其內部包含的自定義渲染邏輯,其靈活性獲得了進一步的提高,只要這三個組件是做爲 toggle 組件的子組件來調用,一切都將正常運行。

你能夠下面的連接來看看這個組件的實現代碼以及演示:

總結

一般狀況下,在設計和實現職能分明的組件時,可使用這種模式,好比 tabstab 組件,tabs 只負責 tab 的滾動、導航等邏輯,而 tab 自己僅負責內容的渲染,就如同這裏的 toggletoggle-button`toggle-ontoggle-off 同樣。

目錄

github gist

歡迎關注公衆號 全棧101,只談技術,不談人生

clipboard.png

相關文章
相關標籤/搜索