uni-app页面中绑定array值,array子元素值更新时页面不响应,必须要有其他值变更触发页面重新渲染时才会同时渲染。

uni-app页面中绑定array值,array子元素值更新时页面不响应,必须要有其他值变更触发页面重新渲染时才会同时渲染。

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

产品分类:uniapp/App

PC开发环境操作系统:Windows

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

HBuilderX类型:正式

HBuilderX版本号:3.2.16

手机系统:Android

手机系统版本号:Android 10

手机厂商:华为

手机机型:all

页面类型:vue

vue版本:vue2

打包方式:云端

项目创建方式:HBuilderX

示例代码:

<template>  
    <view class="content">  
        <view class="text">  
            <text>{{arr[2]}}</text>  
            <text>{{txt}}</text>  
            <text>{{obj.a}}</text>  
        </view>  
        <text class="btn" @click="reVal1">只更新arr</text>  
        <text class="btn" @click="reVal3">只更新obj</text>  
        <text class="btn" @click="reVal4">只更新txt</text>  
        <text class="btn" @click="reVal2">更新arr和txt</text>  
        <view class="text">  
            <text>【只更新arr】时,arr值更了,但页面不响应,只有等到其他值更新触发页面重新渲染才会同时渲染arr到页面</text>  
        </view>  
    </view>  
</template>  

<script>  
export default {  
    data() {  
        return {  
            arr: [1, 2, 3],  
            obj: { a: 1, b: 2 },  
            txt: 0  
        }  
    },  
    methods: {  
        reVal1() {  
            this.arr[2] = Date.now();  
            console.log(this.arr)  
        },  
        reVal3() {  
            this.obj.a = Date.now();  
            console.log(this.obj)  
        },  
        reVal2() {  
            this.arr[2] = Date.now();  
            this.txt = Math.random();  
            console.log(this.arr)  
        },  
        reVal4() {  
            this.txt = Math.random();  
        }  
    }  
}  
</script>  

<style>  
    .content {  
        display: flex;  
        flex-direction: column;  
        align-items: stretch;  
        justify-content: center;  
    }  

    .text {  
        flex: 1;  
        padding: 10px;  
    }  

    .btn {  
        padding: 10px;  
        margin: 10px;  
        text-align: center;  
        background-color: #aaa;  
    }  
</style>  

操作步骤:

在H5、微信、APP中都是这样。

预期结果:

希望也能直接重新渲染

实际结果:

现在只改变array的元素值,页面不更新,只好执行一次this.$forceUpdate();


更多关于uni-app页面中绑定array值,array子元素值更新时页面不响应,必须要有其他值变更触发页面重新渲染时才会同时渲染。的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

不是响应式的,可以使用Vue.set()方法,https://cn.vuejs.org/v2/api/#Vue-set

更多关于uni-app页面中绑定array值,array子元素值更新时页面不响应,必须要有其他值变更触发页面重新渲染时才会同时渲染。的实战教程也可以访问 https://www.itying.com/category-93-b0.html


谢谢。

这是因为Vue 2的响应式系统无法检测到数组元素通过索引直接赋值的变化。

在Vue 2中,响应式系统通过Object.defineProperty实现,它只能监听对象属性的get/set操作。对于数组,Vue重写了数组的7个变异方法(push、pop、shift、unshift、splice、sort、reverse),但直接通过索引修改数组元素(如this.arr[2] = value)不会触发setter,因此不会触发视图更新。

解决方案:

  1. 使用Vue.set或$set方法(推荐):
this.$set(this.arr, 2, Date.now());
// 或
Vue.set(this.arr, 2, Date.now());
  1. 使用splice方法
this.arr.splice(2, 1, Date.now());
  1. 创建新数组
this.arr = [...this.arr.slice(0, 2), Date.now(), ...this.arr.slice(3)];
  1. 对于对象属性,同样的问题也存在。虽然你的示例中obj.a的更新能触发渲染,但如果你给对象添加新属性,也需要使用$set
this.$set(this.obj, 'newProp', value);

在reVal1方法中,应该改为:

reVal1() {
    this.$set(this.arr, 2, Date.now());
    console.log(this.arr)
}
回到顶部