uni-app 页面更新数组类型的变量时 组件的prop使用该变量的表达式赋值 数组更新 组件的prop不会刷新

uni-app 页面更新数组类型的变量时 组件的prop使用该变量的表达式赋值 数组更新 组件的prop不会刷新

信息类别 详情
产品分类 uniapp/小程序/微信
操作系统 Windows
操作系统版本 win10
HBuilderX类型 正式
HBuilderX版本 3.1.22
第三方开发者工具版本 Stable 1.05.2103200
基础库版本 2.18.0
项目创建方式 HBuilderX

示例代码:

Footer:  
<template>  
    <view>  
        {{length1}}|  
        {{length2}}  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {};  
        },  

        components: {},  
        props: {  
            length1: Boolean,  
            length2: Boolean  
        },  
        methods: {}  
    };  
</script>  

Page:  
<template>  
    <view class="content">  
        <image class="logo" src="/static/logo.png"></image>  
        页面的值:  
        <view class="text-area">  
            <text class="title">{{(list1.length>0)}}|{{(list2.length>0)}}</text>  
        </view>  
        <div>组件内的值: <Footer :length1="(list1.length>0)" :length2="(list2.length>0)"></Footer>  
        </div>  
        <button @click="tapAdd">改变值</button>  
    </view>  
</template>  
<script>  
    export default {  
        data() {  
            return {  
                title: 'Hello',  
                i: 0,  
                list1: null,  
                list2: []  
            }  
        },  
        onLoad() {  

        },  
        methods: {  
            tapAdd() {  
                this.i++;  
                if (this.i == 1) {  
                    this.list1 = [];  
                }  
                if (this.i == 2) {  
                    this.list1.push({});  
                }  
                if (this.i == 3) {  
                    this.list1 = [{}];  
                }  
                this.list2.push({});  
            }  
        }  
    }  
</script>

如代码示例。组件Footer中有两个prop,length1和length2,组件中直接显示。赋值时使用判断表达式(list1.length>0)。页面中直接输出表达式的值作为对比。

操作步骤:

多次点击“改变值”按钮,观察页面中显示的数据。

预期结果:

页面中显示的值、组件中显示的值,应该一致才对

实际结果:

点击按钮后修改list1和list2数组。可以发现页面中显示的值与组件中的值并不一致。页面中的值更新了,组件中的值没有更新。

bug描述:

页面更新数组类型的变量、组件的prop使用该变量的表达式赋值,当数组更新时,页面中的变量正常更新,但组件的prop变量不会刷新。(已上传完整测试项目,见附件)

附件下载


更多关于uni-app 页面更新数组类型的变量时 组件的prop使用该变量的表达式赋值 数组更新 组件的prop不会刷新的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

更多关于uni-app 页面更新数组类型的变量时 组件的prop使用该变量的表达式赋值 数组更新 组件的prop不会刷新的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个典型的 uni-app 数据响应式问题。问题出现在数组的响应式更新机制上。

原因分析:

  1. list1 初始值为 null,当执行 this.list1 = [] 时,虽然数组被重新赋值,但基于数组长度的表达式 (list1.length>0) 可能没有正确触发组件的 prop 更新
  2. 直接使用数组的 push 方法在某些情况下可能无法触发 Vue 的响应式更新
  3. 在 prop 中使用表达式赋值时,数组的变化检测可能不够灵敏

解决方案:

  1. 使用 $set 强制更新
tapAdd() {
    this.i++;
    if (this.i == 1) {
        this.$set(this, 'list1', []);
    }
    if (this.i == 2) {
        this.list1.push({});
        this.$forceUpdate(); // 强制更新
    }
    if (this.i == 3) {
        this.$set(this, 'list1', [{}]);
    }
    this.list2.push({});
    this.$forceUpdate(); // 确保更新
}
  1. 改用计算属性传递 在页面组件中:
computed: {
    computedLength1() {
        return this.list1 && this.list1.length > 0;
    },
    computedLength2() {
        return this.list2.length > 0;
    }
}

模板中:

<Footer :length1="computedLength1" :length2="computedLength2"></Footer>
  1. 确保数组初始值正确
data() {
    return {
        list1: [], // 避免使用 null
        list2: []
    }
}
回到顶部