uni-app 模版渲染 v-if v-else-if 逻辑判断问题

uni-app 模版渲染 v-if v-else-if 逻辑判断问题

项目属性 信息
产品分类 uniapp/小程序/阿里
PC开发环境操作系统 Mac
PC开发环境操作系统版本号 macOS Catalina 11.1
HBuilderX类型 正式
HBuilderX版本号 3.1.13
第三方开发者工具版本号 版本2.1.9 (2.1.9)
项目创建方式 HBuilderX

示例代码:

<template>    
    <view>    
        <view @click="toggle">    
            点我    
        </view>   
        {{flag}} {{ isTrue(card.number)}} {{hasOwn(card.number)}}  
        <view v-if="flag && isTrue(card.number) && hasOwn(card.number)">123</view>    
        <view v-else-if="hasOwn(card.number)">456</view>     
    </view>    
</template>    
<script>    
    export default{    
        data() {    
            return {    
                flag: true,    
                card: {    
                    number: [2]    
                }    
            }    
        },    
        methods: {    
            isTrue(item) {    
                return item.some(n => n > 1)    
            },    
            hasOwn(item) {    
                return item.length    
            },    
            toggle() {  
                if (this.card.number[0] > 1) {  
                    this.$set(this.card, 'number', [1])    
                } else {  
                    this.$set(this.card, 'number', [2])    
                }   
                this.$nextTick(() => {    
                    console.log(this.flag && this.isTrue(this.card.number) && this.hasOwn(this.card.number), this.hasOwn(this.card.number))    
                })    
            }    
        }    
    }    
</script>    
<style></style>  

操作步骤:

  • v-if 逻辑永远无法展示

预期结果:

  • 可以依次切换

实际结果:

  • 有一处逻辑无法进入

bug描述:

var render = function() {  
  var _vm = this  
  var _h = _vm.$createElement  
  var _c = _vm._self._c || _h  
  var m0 = _vm.isTrue(_vm.card.number)  
  var m1 = _vm.hasOwn(_vm.card.number)  
  var m2 = _vm.flag && _vm.isTrue(_vm.card.number)  
  var m3 = _vm.$root.m2 && _vm.hasOwn(_vm.card.number)  
  var m4 = !m3 ? _vm.hasOwn(_vm.card.number) : null  
  _vm.$mp.data = Object.assign(  
    {},  
    {  
      $root: {  
        m0: m0,  
        m1: m1,  
        m2: m2,  
        m3: m3,  
        m4: m4  
      }  
    }  
  )  
}  

更多关于uni-app 模版渲染 v-if v-else-if 逻辑判断问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

HX更新至最新版试试

更多关于uni-app 模版渲染 v-if v-else-if 逻辑判断问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html


一样的 就是新版本出问题往回切都是一样的问题

目前暂时把这逻辑放在函数中判断执行 避免这bug

只是这里模版的较复杂判断 上次提交过一类似bug 官方修复了 上次地址: https://ask.dcloud.net.cn/question/105048 官方模版这里代码是不是要review下或者添加详细注释 这次在这里又出现类似bug

问题确认,已加分,后续修复。
HBuilderX alpha 3.4.8 已修复
3.4.7 版本临时解决方案,执行 npx patch-hbuilderx-plugins 修复

这是一个典型的uni-app模板渲染优化问题。根据你提供的代码和编译后的render函数,问题出在uni-app对v-if和v-else-if的编译优化上。

从编译结果可以看到:

  1. m2 = _vm.flag && _vm.isTrue(_vm.card.number) 缺少了_vm.hasOwn(_vm.card.number)
  2. m3 = _vm.$root.m2 && _vm.hasOwn(_vm.card.number) 使用了错误的$root.m2引用

这导致v-if条件判断错误。解决方案是避免在模板中使用复杂的逻辑表达式,特别是包含方法调用的组合条件。

建议修改为:

<template>    
    <view>    
        <view @click="toggle">点我</view>   
        {{flag}} {{ isTrue(card.number)}} {{hasOwn(card.number)}}  
        <view v-if="showFirst">123</view>    
        <view v-else-if="showSecond">456</view>     
    </view>    
</template>    

<script>    
export default {    
    data() {    
        return {    
            flag: true,    
            card: {    
                number: [2]    
            }    
        }    
    },    
    computed: {    
        showFirst() {    
            return this.flag && this.isTrue(this.card.number) && this.hasOwn(this.card.number)    
        },    
        showSecond() {    
            return this.hasOwn(this.card.number)    
        }    
    },    
    methods: {    
        isTrue(item) {    
            return item.some(n => n > 1)    
        },    
        hasOwn(item) {    
            return item.length    
        },    
        toggle() {  
            if (this.card.number[0] > 1) {  
                this.$set(this.card, 'number', [1])    
            } else {  
                this.$set(this.card, 'number', [2])    
            }   
        }    
    }    
}    
</script>
回到顶部