微信小程序selectComponent返回null的問題排查與分析

       要想小程序界面好看,還原UI妹紙設計的界面,小程序自帶的組件肯定是無法滿足所有需求的。那想要還原比較炫酷好看的UI的時候就必不可少需要自定義組件了。寫過許多自定義組件了,也遇到過許多坑,這裏說一個比較頭大的坑,就是引入自定義組建的時候,使用selectComponent獲取自定義組件對象時,返回null的問題。

      簡單示例

   因爲這裏我們說的主要是selectComponent返回爲null的問題,其他問題先不考慮,這裏假設我有一個自定義組件QrCodeDialog,且自定義組件的代碼沒有問題(組件代碼本身的問題就不在本次討論範圍了)。

這個時候我在Main界面引用了QrCodeDialog,卻發現this.selectComponent()方法返回的null。

問題排查與分析

  1.那首先最基本的就是看頁面的json引用路徑是否正確

2.看看wxml文件裏面的選擇器是否設置選擇器,比如我這裏設置的是id選擇器

(這裏提一下自定義組件使用什麼名字的標籤是由頁面的json文件中引用自定義組件時的key決定的,比如我引用的時候key定義的是qrcode_dialog,那麼在wxml文件使用的時候組件名就是qrcode_dialog,這個大家應該都知道^_^)

3.看看在頁面的js文件裏面引用的代碼

注意這個selectComponent方法裏面的參數要與wxml裏面設置的id選擇器的值相對應,比如我的用的id選擇器就用#號+id

 

如果檢查過後上面說的,全都沒問題的話,那多半就是wxml中自定義組件的那段代碼還沒渲染到就使用selectComponent引用了組件,這個時候的返回值肯定是null。產生這種大致就下面兩種情況。

1.wx:if屬性使用不當。

     爲什麼說wx:if使用不當會導致selectComponent返回爲null呢?這裏不得不提一下wx:if與hidden屬性的區別,這兩個屬性我想大家都比較熟悉,都是用來控制顯示與隱藏的。要說有什麼區別,有些可愛的同學就會脫口而出:“wx:if條件爲true就顯示,反之則隱藏;hidden條件爲true就隱藏,反之則顯示!”。嗯,說的沒錯,這確實是最直觀最明顯的區別。但是說的並不全!他們還有一個區別,就是如果你用wx:if包裹了一段代碼,界面在渲染的時候,當wx:if的條件爲false的時候是不會渲染這段代碼的,只有wx:if的條件爲true纔會渲染這段代碼;而用hidden包裹的代碼無論條件是爲true還是false都會渲染它包裹的代碼,只不過爲true時將這段佈局隱藏了而已。

 

    說到這個區別我想有些小可愛已經明白了。假如你的自定義組件包裹在了wx:if下,並且在你使用selectComponent獲取組件對象的時候,這個wx:if的條件還爲false,也就是說你引用的時候,頁面並沒有渲染到你的自定義組件,這時候使用selectComponent獲取的組件對象當然爲空,因爲都還沒渲染到。

舉個簡單的例子:

wxml文件

<view wx:if="{{a==1}}">
   <qrcode_dialog id="vipQrcode1" />
</view>

qrcode_dialog 是我的自定義組件,使用view包裹,並使用wx:if添加條件如果a==1就顯示

js文件添加引用代碼

    this.vipQrcode1 = this.selectComponent("#vipQrcode1")
    console.log("第一次---this.vipQrcode1====", this.vipQrcode1)
    this.setData({
      a:1
    })
    this.vipQrcode1 = this.selectComponent("#vipQrcode1")
    console.log("第二次--=this.vipQrcode1====", this.vipQrcode1)

這裏我先直接引用一次,打印一次日誌,再看看賦值a爲1之後再引用打印一次日誌,看看效果:

很顯然第一次的時候由於不滿足a==1的條件,selectComponent返回的是null,當我賦值了a=1時,這時候滿足了if條件,我再次引用就不爲空了。

我們在將wx:if換成hidden看看有什麼區別,只需要改下wxml文件的代碼:

<view hidden="{{a!=1}}">
  <qrcode_dialog id="vipQrcode1" isShow="{{false}}" />
</view>

hidden的條件就是a!=1就隱藏,js還是之前的代碼,先直接引用一次,打印一次日誌,再賦值a爲1之後再引用打印一次日誌,我就不貼了,再看看日誌

很顯然當我換成了hidden之後,無論是否滿足條件selectComponent都不爲空。

   說到這裏,趕緊看看你頁面的wxml文件的佈局文件,是不是將自定義組件放在了wx:if裏面包裹起來了,並且你引用的時候wx:if的條件是不是爲false。如果真的是這種情況導致的就將wx:if換成hidden就好了。

2.自定義組件所在層級太深

       這個意思就是說你的自定義組件嵌套在n個view下面,理論上頁面渲染的順序應該是從外往裏,如果你的自定義組件嵌套的非常深,而這個時候你在頁面還未渲染完成的時候就開始使用selectComponent引用組件,獲取到的對象也有可能是會爲null,這個情況不會太穩定,有時候渲染的速度不一樣,出現偶爾引用成功,偶爾引用失敗的情況。當然這種情況極少出現,反正我這輩子沒遇見過。哈哈~誇張了一些,反正我是沒遇到過這種情況,不過理論上應該是存在這種情況的。如果真的遇到了這種情況,你可以沒必要急着一開始就去引用它,你也可以延遲幾秒鐘再引用,或者在你需要使用自定義組件裏的方法時再引用。

 

說了這麼多,其實只要記住this.selectComponent()返回爲null的情況無外乎就是兩種,要麼是引用錯誤,要麼就是未找到自定義組件節點,在發現其他情況的話我在補充。

 

 

發佈了8 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章