摘要:你可以下面的鏈接來看看這個組件的實現(xiàn)代碼以及演示在線演示總結(jié)當期望獲得子元素或者子組件的引用時,切記使用和來解決問題。
05 使用 $refs 訪問子組件引用 目標
在之前的文章中,詳細闡述了子組件獲取父組件所提供屬性及方法的一些解決方案,如果我們想在父組件之中訪問子組件的一些方法和屬性怎么辦呢?設想以下一個場景:
當前的 custom-button 組件中,有一個 input 元素
我們期望當 toggle 的開關(guān)狀態(tài)為開時,顯示 input 元素并自動獲得焦點
這里要想完成目標,需要獲取某個組件或者每個元素的引用,在不同的 mvvm 框架中,都提供了相關(guān)特性來完成這一點:
angularjs: 可以使用依賴注入的 $element 服務
Angular: 可以使用 ViewChild、ContentChild 或者 template ref 來獲取引用
react: 使用 ref 屬性聲明獲取引用的邏輯
在 vue 中,獲取引用的方法與 react 類似,通過聲明 ref 屬性來完成。
實現(xiàn)首先,在 custom-button 組件中增加一個 input 元素,如下:
注意這里的 ref="input",這樣在組件內(nèi)部,可以通過 this.$refs.input 獲得該元素的引用,為了實現(xiàn)目標中提及的需求,再添加一個新的方法 focus 來使 input 元素獲取焦點,如下:
focus() { this.$nextTick(function() { this.$refs.input.focus(); }); },
注意這里的 this.$nextTick,正常情況下,直接調(diào)用 input 的 focus 方法是沒有問題的,然而卻不行。因為 input 的渲染邏輯取決于 prop 屬性 on 的狀態(tài),如果直接調(diào)用 focus 方法,這時 input 元素的渲染工作很可能還未結(jié)束,這時 this.$refs.input 所指向的引用值為 undefined,繼續(xù)調(diào)用方法則會拋出異常,因此我們利用 this.$nextTick 方法,將調(diào)用的邏輯延遲至下次 DOM 更新循環(huán)之后執(zhí)行。
同理,在 app 組件中,為 custom-button 添加一個 ref 屬性,如下:
之后修改 onToggle 方法中的邏輯以滿足目標中的需求,當 toggle 組件狀態(tài)為開時,調(diào)用 custom-button 組件的 focus 方法,如下:
onToggle(on) { if (on) this.$refs.customButton.focus(); console.log("toggle", on); }成果
點擊按鈕會發(fā)現(xiàn),每當開關(guān)為開時,input 元素都會顯示,并會自動獲得焦點。
你可以下面的鏈接來看看這個組件的實現(xiàn)代碼以及演示:
sandbox: 在線演示
github: part-5
總結(jié)當期望獲得子元素或者子組件的引用時,切記使用 ref 和 $refs 來解決問題。文章中所舉例子的交互,在實際場景中很常見,比如:
當通過一個 icon 觸發(fā)搜索框時,期望自動獲得焦點
當表單校驗失敗時,期望自動獲得發(fā)生錯誤的表單項的焦點
當復雜列表的篩選器展開時,期望第一個篩選單元獲得焦點
這幾種情況下,都可以使用該模式來高效地解決問題,而不是通過使用 DOM 中的 api 或者引入 jquery 獲取相關(guān)元素再進行操作。
目錄github gist
歡迎關(guān)注公眾號 全棧101,只談技術(shù),不談人生
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/98536.html
摘要:寫在前頭去年,曾經(jīng)閱讀過一系列關(guān)于高級組件模式的文章,今年上半年,又抽空陸陸續(xù)續(xù)地翻譯了一系列關(guān)于高級組件模式的文章,碰巧最近接手了一個公司項目,前端這塊的技術(shù)棧是。同時這個組件還擁有一個屬性,用來初始化的狀態(tài)值。 寫在前頭 去年,曾經(jīng)閱讀過一系列關(guān)于高級 react 組件模式的文章,今年上半年,又抽空陸陸續(xù)續(xù)地翻譯了一系列關(guān)于高級 angular 組件模式的文章,碰巧最近接手了一個公...
摘要:之后再引入該指令,如下之后就可以在組件的模板中使用該指令了,比如一切都將按預期中運行,當組件的狀態(tài)為開時,組件的根元素會增加一個的內(nèi)容增強屬性。到后來興起了組件化開發(fā)的開發(fā)思想,指令似乎是隨著的沒落而消失了蹤影。 06 通過 directive 增強組件內(nèi)容 目標 之前的五篇文章中,switch 組件一直是被視為內(nèi)部組件存在的,細心的讀者應該會發(fā)現(xiàn),這個組件除了幫我們提供開關(guān)的交互以外...
摘要:在中,我們是否也有一些手段或特性來提高組件的復用程度和靈活性呢答案當然是有的,那就是。成果通過實現(xiàn),我們成功將注入的邏輯抽離了出來,這樣每次需要共享組件的狀態(tài)和方法時,混入該即可。 03 使用 mixin 來增強 Vue 組件 目標 之前一篇文章中,我們雖然將 toggle 組件劃分為了 toggle-button、toggle-on 和 toggle-off 三個子組件,且一切運行良...
摘要:編寫復合組件目標我們需要實現(xiàn)的需求是能夠使使用者通過組件動態(tài)地改變包含在它內(nèi)部的內(nèi)容。成果通過復合組件的方式,我們將組件劃分為了三個更小的職責更加單一的子組件。 02 編寫復合組件 目標 我們需要實現(xiàn)的需求是能夠使使用者通過 組件動態(tài)地改變包含在它內(nèi)部的內(nèi)容。 熟悉 vue 的童鞋可能馬上會想到不同的解決方案,比如使用 slot 并配合 v-if,我們這里采用另外一種方法,利用 vu...
摘要:在中,這種類型的組件也可以叫做函數(shù)式組件。這種組件和普通組件相比的優(yōu)勢主要在于,它是無狀態(tài)的,這意味著它的可測試性和可讀性更好,同時一些情況下,渲染開銷也更小。 09 使用 Functional 組件 目標 到此為止,我們的 toggle 組件已經(jīng)足夠強大以及好用了,因此這篇文章不會再為它增加新的特性。如果你是從第一篇文章一直讀到這里的讀者,你一定會發(fā)現(xiàn),整篇文章中,我?guī)缀鯖]有對 to...
閱讀 2613·2023-04-25 22:09
閱讀 2845·2021-10-14 09:47
閱讀 1941·2021-10-11 11:10
閱讀 2694·2021-10-09 09:44
閱讀 3390·2021-09-22 14:57
閱讀 2503·2019-08-30 15:56
閱讀 1622·2019-08-30 15:55
閱讀 782·2019-08-30 14:13