uni-app 直接写在模板语法中的短路逻辑有问题, 写在方法中没有问题

uni-app 直接写在模板语法中的短路逻辑有问题, 写在方法中没有问题

开发环境 版本号 项目创建方式
Windows windows 10 HBuilderX

示例代码:

<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编译后的代码:

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

    var m0 = _vm.checkStartGoodsGroupon(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
    }
})

修改后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"

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


更多关于uni-app 直接写在模板语法中的短路逻辑有问题, 写在方法中没有问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

12 回复

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

更多关于uni-app 直接写在模板语法中的短路逻辑有问题, 写在方法中没有问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html


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

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

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

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

问题确认,已加分,后续会考虑优化
已确认问题:当模板中的表达式计算带有副作用时,结果可能和预判不符。
尽管十三分不推荐在模板中使用带有副作用的表达式,但是后续仍然会优化这一问题。

终于收到官方回信了, 感动, 辛苦大家了 希望尽快解决, 这个确实是很常用的语法, 现在只能 使用三元表达式, 或者独立成方法, 这两种一个阅读复杂, 一个方法抽离过多, 也阅读复杂

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

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

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

HBuilderX 3.1.10 alpha 已修复

这是因为uni-app在模板编译时对短路逻辑的处理机制导致的。当你在模板中直接使用item.goodsGrouponList.length>0 && !checkStartGoodsGroupon(item)时,uni-app编译器会将整个表达式都进行求值,即使item.goodsGrouponList.length>0为false,checkStartGoodsGroupon(item)方法仍然会被调用。

从你提供的编译后代码可以看出:

  • 修改前:var m0 = _vm.checkStartGoodsGroupon(item) - 方法被直接调用
  • 修改后:var m0 = _vm.lib1(item) - 通过lib1方法封装,在方法内部处理短路逻辑

在你的checkStartGoodsGroupon方法中,当item.goodsGrouponList为空数组时,访问item.goodsGrouponList[0].price就会报错"undefined"。

解决方案: 将短路逻辑封装在methods方法中是正确做法,这样可以确保短路逻辑按预期工作。或者你也可以在checkStartGoodsGroupon方法内部添加空值检查:

checkStartGoodsGroupon(item){
    if(item.goodsGrouponList.length === 0) return false;
    item.goodsGrouponList[0].price = 100;
    // ...其他逻辑
}
回到顶部