跨層級的獲取組件實例
若是是普通的元素,ref="p"獲取的是真實的dom元素,若是是自定義組件,那麼獲取到的就是這個組件的實例了。
this.$ref.XXXX能夠獲取當前組件上下文的實例。若是說要獲取跨層級的組件的實例?那就很不方便了。
若是要獲取父組件的,能夠經過parent.refs.
獲取子組件的children.refs
若是層級多的時候,10級20級別的。那就很不方便了。
若是A組件要訪問E組件的實例。或者是F要訪問A組件的實例。第一種想法多是經過遞歸的方式一直層級的網上找parent。一層層的去查找目標實例,
遞歸繁瑣,並且性能低效。每次訪問實例都要走一遍遞歸的形式,由於你的實例是不能被緩存 的,而後你底層的子組件的實例,若是被更新了。你父組件是不能及時的知道它這個實例是更新了。因此說你每次使用的時候,都須要層級的去獲取。就是你沒有辦法去緩存。
爭對這種狀況設計了一種更加高效的方案。。若是你熟悉react ref它是一個call back回調的形式,這樣咱們在回調中就能夠作不少的事情,就比較靈活了。
爭對這種回調靈活的特色,咱們能夠設定一種主動通知,主動獲取這樣一種方案。
加入A要獲取E的實例,A只須要提供一個鉤子函數,E實例生成或者更新以後,主動的去調用這個溝子函數,來通知A節點,我這個實例已經生成好了。我這個實例有更新,只須要告訴這個A節點,A節點將這個實例進行緩存就能夠了。而後每次A節點須要訪問的時候,它老是能拿到最新的 ,由於E節點更新的時候已經主動的告訴了A節點。
如何實現callback的 ref就成了咱們一個新的難點,
vue
看demo
仍是和上一節的結構是一致的。
點擊獲取到了E節點
F節點能夠跨層級的獲取到A節點。
A節點經過provide提供了主動通知和主動獲取的幾個鉤子函數,
get就是直接去獲取name的ref
子節點是如何調用setChildrenRef,經過inject注入,而後經過v-ant-ref的形式,經過這樣一個指令,這個指令是咱們本身去開發的,把它變成一個回調的形式。
每次childrenH更新或者實例化完成的時候,都會主動的調用咱們的回調.主動通知上層的節點。去告訴他,我節點更新了。
爲何叫作v-ant-ref 之內vue 1.0的版本有v-ref這樣一個指令,爲了防止和之後的指令衝突。
v-ant-ref就是一個自定義的指令
bind的時候,綁定的時候,,把咱們的實例,調用這個回調。傳遞過去。
更新的時候,把新的實例主動告訴上層的節點。
F節點,只須要注入getParentChildrenRef,這個名字能夠隨便取
這就是咱們說的如何優雅的去獲取跨層級的組件,避免了使用回調,充分利用緩存機制,避免去執行遞歸的方式,
react
課後習題