在每一個new Vue實例的子組件中,其根實例能夠經過$root屬性進行訪問。
例子:數組
// Vue 根實例 new Vue({ data: { foo: 1 }, computed: { bar: function () { /* ... */ } }, methods: { baz: function () { /* ... */ } } })
全部的子組件均可以將這個實例做爲一個全局store來訪問或使用。ide
/ 獲取根組件的數據 this.$root.foo // 寫入根組件的數據 this.$root.foo = 2 // 訪問根組件的計算屬性 this.$root.bar // 調用根組件的方法 this.$root.baz()
注意:
對於demo或很是小型的有少許組件的應用來講這是很方便的。不過這個模式擴展到中大型應用來講就不合適了。所以在絕大多數狀況下,咱們強烈推薦使用Vuex來管理應用的狀態。this
和$root相似,$parent屬性能夠用來從一個子組件訪問父組件的實例。它提供了一種機會,能夠在後期隨時觸達父級組件,以替代將數據以prop的方式傳入子組件的方式。
注意:google
在絕大多數狀況下,觸達父級組件會使得你的應用更難調試和理解,尤爲是當你變動了父級組件的數據的時候。當咱們稍後回看那個組件的時候,很難找出那個變動是從哪裏發起的。
## 訪問子組件實例或子元素 ##
儘管存在prop和事件,有的時候你仍可能須要在Javascript裏直接訪問一個子組件。爲了達到這個目的,你能夠經過ref特性爲這個子組件賦予一個ID引用。例如:設計
<base-input ref="usernameInput"></base-input>
如今在你已經定義了這個ref的組件裏,你能夠使用:調試
this.$refs.usernameInput
來訪問這個 <base-input> 實例,以便不時之需。
當 ref 和 v-for 一塊兒使用的時候,你獲得的引用將會是一個包含了對應數據源的這些子組件的數組。
注意:code
$refs 只會在組件渲染完成以後生效,而且它們不是響應式的。這僅做爲一個用於直接操做子組件的「逃生艙」——你應該避免在模板或計算屬性中訪問 $refs。
<google-map> <google-map-region v-bind:shape="cityBoundaries"> <google-map-markers v-bind:places="iceCreamShops"></google-map-markers> </google-map-region> </google-map>
在這個組件裏,全部<google-map>的後代都須要訪問一個getMap方法,以便知道要跟哪一個地圖進行交互。不幸的是,使用$parent屬性沒法很好的擴展到更深層級的嵌套組件上。這也是依賴注入的用武之地,它用到了兩個新的實例屬性:provide和inject。
provide選項容許咱們指定咱們想要提供給後代組件的數據/方法。在這個例子中,就是<google-map>內部的getMap方法:接口
provide(){ return{ getMap:this.getMap } }
而後在任何後代組件裏,咱們均可以經過使用inject選項來接收指定的咱們想要添加在這個實例上的屬性:事件
inject:['getMap']
相比$parent來講,這個用法可讓咱們在任意後代組件中訪問getMap,而不須要暴露整個<google-map>實例。這容許咱們更好的持續研發該組件,而不須要擔憂咱們可能會改變/移除一些子組件依賴的東西。同時這些組件之間的接口是始終明肯定義的,就和props同樣。
祖先組件不須要知道哪些後代組件使用它提供的屬性
後代組件不須要知道被注入的屬性來自哪裏
注意:ip
然而,依賴注入仍是有負面影響的。它將你的應用以目前的組件組織方式耦合了起來,使重構變得更加困難。同時所提供的屬性是非響應式的。這是出於設計的考慮,由於使用它們來建立一箇中心化規模化的數據跟使用 $root作這件事都是不夠好的。若是你想要共享的這個屬性是你的應用特有的,而不是通用化的,或者若是你想在祖先組件中更新所提供的數據,那麼這意味着你可能須要換用一個像 Vuex 這樣真正的狀態管理方案了。