vue訪問元素&元件
訪問根例項
在每個new Vue例項的子元件中,其根例項可以通過$root屬性進行訪問。
例子:
// Vue 根例項 new Vue({ data: { foo: 1 }, computed: { bar: function () { /* ... */ } }, methods: { baz: function () { /* ... */ } } })
所有的子元件都可以將這個例項作為一個全域性store來訪問或使用。
/ 獲取根元件的資料 this.$root.foo // 寫入根元件的資料 this.$root.foo = 2 // 訪問根元件的計算屬性 this.$root.bar // 呼叫根元件的方法 this.$root.baz()
注意:
對於demo或非常小型的有少量元件的應用來說這是很方便的。不過這個模式擴充套件到中大型應用來說就不合適了。因此在絕大多數情況下,我們強烈推薦使用Vuex來管理應用的狀態。
訪問父元件例項
和$root類似,$parent屬性可以用來從一個子元件訪問父元件的例項。它提供了一種機會,可以在後期隨時觸達父級元件,以替代將資料以prop的方式傳入子元件的方式。
注意:
在絕大多數情況下,觸達父級元件會使得你的應用更難除錯和理解,尤其是當你變更了父級元件的資料的時候。當我們稍後回看那個元件的時候,很難找出那個變更是從哪裡發起的。
## 訪問子元件例項或子元素 ##
儘管存在prop和事件,有的時候你仍可能需要在Javascript裡直接訪問一個子元件。為了達到這個目的,你可以通過ref特性為這個子元件賦予一個ID引用。例如:
<base-input ref="usernameInput"></base-input>
現在在你已經定義了這個ref的元件裡,你可以使用:
this.$refs.usernameInput
來訪問這個 <base-input> 例項,以便不時之需。
當 ref 和 v-for 一起使用的時候,你得到的引用將會是一個包含了對應資料來源的這些子元件的陣列。
注意:
$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一樣。
祖先元件不需要知道哪些後代元件使用它提供的屬性
後代元件不需要知道被注入的屬性來自哪裡
注意:
然而,依賴注入還是有負面影響的。它將你的應用以目前的元件組織方式耦合了起來,使重構變得更加困難。同時所提供的屬性是非響應式的。這是出於設計的考慮,因為使用它們來建立一箇中心化規模化的資料跟使用 $root做這件事都是不夠好的。如果你想要共享的這個屬性是你的應用特有的,而不是通用化的,或者如果你想在祖先元件中更新所提供的資料,那麼這意味著你可能需要換用一個像 Vuex 這樣真正的狀態管理方案了。