微信小程序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的情况无外乎就是两种,要么是引用错误,要么就是未找到自定义组件节点,在发现其他情况的话我在补充。

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值