1***@qq.com
1***@qq.com
  • 发布:2021-03-11 18:00
  • 更新:2021-04-16 11:05
  • 阅读:879

【报Bug】uni 直接写在模板语法中的短路逻辑有问题, 写在方法中没有问题

分类:uni-app

产品分类: uniapp/小程序/微信

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: windows 10

HBuilderX类型: 正式

HBuilderX版本号: 3.1.4

第三方开发者工具版本号: 1.03.2005140

基础库版本号: 2.15.0

项目创建方式: HBuilderX

示例代码:

原代码:

<text v-show="item.goodsGrouponList.length>0 && !checkStartGoodsGroupon(item)" class="nostart-ico">  
    拼团预告  
</text>  

...  

methods:{  
    checkStartGoodsGroupon(item){  
        item.goodsGrouponList[0].price = 100;  
    }  
}

按逻辑应该第一个会是false 后面就不会执行, 但是却进去了, 导致报错, 因为length 为0

uni编译后的代码:

var l0 = _vm.__map(_vm.goodsList, function(item, index) {  
    var $orig = _vm.__get_orig(item)  

    var m0 = _vm.checkStartGoodsGroupon(item) //注释: 怀疑是这个, 编译后的代码把方法放到前面了, 或者是编译器忽略了 前面>0 的条件  
    var m1 =  
      item.goodsGrouponList.length > 0 && _vm.hasAuthStatus  
        ? _vm.calculateGoodsGrouponPriceShowPrice(item)  
        : null  
    var m2 = !(item.goodsGrouponList.length > 0)  
      ? _vm.calculatePriceShow(item)  
      : null  
    var m3 = _vm.calculatePriceShow(item)  
    var m4 = _vm.calculatePriceShow(item)  
    return {  
      $orig: $orig,  
      m0: m0,  
      m1: m1,  
      m2: m2,  
      m3: m3,  
      m4: m4  
    }  
  })

修改后:

<text v-show="lib1(item)" class="nostart-ico">  
    拼团预告  
</text>  

....  

methods:{  
    checkStartGoodsGroupon(item){  
        item.goodsGrouponList[0].price = 100;  
    },  
    lib1(item){  
        return (item.goodsGrouponList.length>0 && !this.checkStartGoodsGroupon(item));  
    }  
}

独立成方法就不会报错, 根据断点发现, 应该是uni生成相应代码的时候 把 逻辑短路 的右侧代码放到前面去了

uni编译后的代码

 var l0 = _vm.__map(_vm.goodsList, function(item, index) {  
    var $orig = _vm.__get_orig(item)  

    var m0 = _vm.lib1(item)  
    var m1 =  
      item.goodsGrouponList.length > 0 && _vm.hasAuthStatus  
        ? _vm.calculateGoodsGrouponPriceShowPrice(item)  
        : null  
    var m2 = !(item.goodsGrouponList.length > 0)  
      ? _vm.calculatePriceShow(item)  
      : null  
    var m3 = _vm.calculatePriceShow(item)  
    var m4 = _vm.calculatePriceShow(item)  
    return {  
      $orig: $orig,  
      m0: m0,  
      m1: m1,  
      m2: m2,  
      m3: m3,  
      m4: m4  
    }  
  })

操作步骤:
<text v-show="item.goodsGrouponList.length>0 && !checkStartGoodsGroupon(item)" class="nostart-ico">  
    拼团预告  
</text>  

...  

methods:{  
    checkStartGoodsGroupon(item){  
        item.goodsGrouponList[0].price = 100;  
    }  
}

预期结果:

原生不显示

实际结果:

报错,
Error in render: "TypeError: Cannot read property 'price' of undefined"

因为&&的右边代码被调用了

bug描述:

示例代码:

<text v-show="item.goodsGrouponList.length>0 && !this.checkStartGoodsGroupon(item)" class="nostart-ico">  
    拼团预告  
</text>  

预期效果:

2021-03-11 18:00 负责人:无 分享
已邀请:
1***@qq.com

1***@qq.com (作者)

这么大的问题, 没人感兴趣吗? 这个可是基础耶, 经常用的哇

1***@qq.com

1***@qq.com (作者)

官方不理, 只能把所有 || 和 && 全部改写成 三元表达式, 三元表达式就没有问题了, 但是太不方便阅读了, 这个问题大家都不关心吗, 这么基础的东西, 大家常用

  • DCloud_UNI_GSQ

    来喽,不是不理,由于手速限制,有时候会延迟或者漏掉

    2021-03-18 18:13

  • DCloud_UNI_GSQ

    因为其中包含小程序不支持的复杂的表达式,所以编译的时候会分解为支持的语句,基础的用法使用一般没有问题。

    2021-03-18 18:28

1***@qq.com

1***@qq.com (作者)

用vue测试了, vue可以使用 && 和 || , 是正常的 ,但是uni中这种写法就有问题, 应该是uni重构的代码, 解析模板语法的时候, || 和 && 没有根据前置条件进行判断

DCloud_UNI_GSQ

DCloud_UNI_GSQ

问题确认,已加分,后续会考虑优化

已确认问题:当模板中的表达式计算带有副作用时,结果可能和预判不符。

尽管十三分不推荐在模板中使用带有副作用的表达式,但是后续仍然会优化这一问题。

  • 1***@qq.com (作者)

    终于收到官方回信了, 感动, 辛苦大家了

    希望尽快解决, 这个确实是很常用的语法,

    现在只能 使用三元表达式, 或者独立成方法, 这两种一个阅读复杂, 一个方法抽离过多, 也阅读复杂

    2021-03-19 10:06

  • 1***@qq.com (作者)

    回复 DCloud_UNI_GSQ: 但是这个是常用的呀, 一个页面肯定会有很多判定, 如果每个判定都抽离出来放到 methods中, 那methods 不会更加过于臃肿吗, 而且 三元表达式是正常的, 所以这只是编译后对短路逻辑的编译问题

    2021-03-19 15:48

  • 1***@qq.com (作者)

    回复 DCloud_UNI_GSQ: 或者可以尝试吧短路逻辑的编译后的语法, 改成三元表达式的, 这样不就可以啦, 对你们应该工作量也少些

    2021-03-19 16:01

  • DCloud_UNI_GSQ

    回复 1***@qq.com: 提醒你不要在模板里写带有副作用(赋值)的表达式是另外一件事

    2021-03-19 16:24

DCloud_UNI_GSQ

DCloud_UNI_GSQ

HBuilderX 3.1.10 alpha 已修复

该问题目前已经被锁定, 无法添加新回复