uni-app picker-view 动态修改 picker-view-column 遍历的值且修改picker-view自身的 value 后,在微信小程序端显示不正确,H5正常

uni-app picker-view 动态修改 picker-view-column 遍历的值且修改picker-view自身的 value 后,在微信小程序端显示不正确,H5正常

示例代码:

<template>  
    <view>  
        <page-head :title="title"></page-head>  
        <view class="uni-padding-wrap">  
            <view class="uni-title">  
                日期:{{year}}年{{month}}月{{day}}日  
            </view>  
        </view>  
        <picker-view v-if="visible" :indicator-style="indicatorStyle" :mask-style="maskStyle" :value="value"  
            @change="bindChange">  
            <picker-view-column>  
                <view class="item" v-for="(item,index) in years" :key="index">{{item}}年</view>  
            </picker-view-column>  
            <picker-view-column>  
                <view class="item" v-for="(item,index) in months" :key="index">{{item}}月</view>  
            </picker-view-column>  
            <picker-view-column>  
                <view class="item" v-for="(item,index) in days" :key="index">{{item}}日</view>  
            </picker-view-column>  
        </picker-view>  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            const date = new Date()  
            const years = []  
            const year = date.getFullYear()  
            const months = []  
            const month = date.getMonth() + 1  
            const days = []  
            const day = date.getDate()  

            for (let i = 2023; i <= date.getFullYear(); i++) {  
                years.push(i)  
            }  

            for (let i = 4; i <= 12; i++) {  
                months.push(i)  
            }  

            for (let i = 1; i <= 31; i++) {  
                days.push(i)  
            }  
            return {  
                title: 'picker-view',  
                years,  
                year,  
                months,  
                month,  
                days,  
                day,  
                value: [1, 0, day - 1],  
                /**  
                 * 解决动态设置indicator-style不生效的问题  
                 */  
                visible: true,  
                // indicatorStyle: `height: ${Math.round(uni.getSystemInfoSync().screenWidth/(750/100))}px;`  
                indicatorStyle: `height: 50px;`,  
                // #ifdef MP-KUAISHOU  
                maskStyle: "padding:10px 0"  
                // #endif  
                // #ifndef MP-KUAISHOU  
                maskStyle: ""  
                // #endif  
            }  
        },  

        watch: {  
            value(newV, oldV) {  
                if (oldV[0] !== newV[0]) { // 改变年  
                    this.months = []  
                    for (let i = 1; i <= 12; i++) {  
                        this.months.push(i)  
                    }  
                    this.value[1] = 9 // 保证月份不变  
                }  
                console.log(this.value);  
            }  
        },  

        methods: {  
            bindChange(e) {  
                this.value = e.detail.value  
            }  
        }  
    }  
</script>  

<style>  
    picker-view {  
        width: 100%;  
        height: 600rpx;  
        margin-top: 20rpx;  
    }  

    .item {  
        line-height: 100rpx;  
        text-align: center;  
    }  
</style>

操作步骤:

注意:2024年的月份是从4月开始的

  1. 将月份调整到 10 月
  2. 切换年份到 2023 年

预期结果:

在微信小程序端,切换 2023 年后应该显示为 10 月

在 H5 端显示正确

实际结果:

在微信小程序端,显示的是 9 月

bug描述:

使用 picker-view 开发自定义的日期选择器

当动态的修改 picker-view-column 内遍历的值,且修改 picker-value 自身的 value 后

在微信小程序端显示错误,H5正常


更多关于uni-app picker-view 动态修改 picker-view-column 遍历的值且修改picker-view自身的 value 后,在微信小程序端显示不正确,H5正常的实战教程也可以访问 https://www.itying.com/category-93-b0.html

20 回复

推测是微信小程序的数据与索引问题 经过我的测试,可以使用这种方法解决
this.$nextTick(()=>{
this.value[1] = 9
})

更多关于uni-app picker-view 动态修改 picker-view-column 遍历的值且修改picker-view自身的 value 后,在微信小程序端显示不正确,H5正常的实战教程也可以访问 https://www.itying.com/category-93-b0.html


感谢你的回复,我试了你的方法,并没有复现成功。

麻烦贴一下全部的代码吧,我这边试试。

回复 4***@qq.com: 在watch那改 watch: { value(newV, oldV) { if (oldV[0] !== newV[0]) { // 改变年 this.months = [] for (let i = 1; i <= 12; i++) { this.months.push(i) } this.$nextTick(()=>{ this.value[1] = 9 }) } console.log(this.value); } },

视频,图片不是

用了微信小程序原生开发试了下,没有问题
测试用代码片段:
https://developers.weixin.qq.com/s/fPdRjbmz7vQA

@yuhespace
感谢你的代码,我试了没成功,还发现了新的bug,你试试这个代码能工作正常么:
watch: {
value(newV, oldV) {
console.log(newV, oldV);

            this.value[1] = 5  

            console.log(this.value);  
        }  
    }

我这边只有第一次是正常的,后续改变月份,对value的改变,无法改变 picker-view 的显示
在 H5 端工作是正常的
在微信小程序原生工作也是正常的:
https://developers.weixin.qq.com/s/lVmnNbms7AQc

我理解没错的话,你这是想让每次你变月份都变成9是吧,因为你的数组一开始从4开始,你加了$nextTick不就行了吗,看我上次的视频

回复 yuhespace: 不是上次是上传

回复 yuhespace: 你使用的 HBuilder 版本是多少?我的是 3.99,我感觉咱们代码行为不一致

回复 4***@qq.com: 我是最新版的4.08

回复 yuhespace: 感谢,用 vue3 + 4.08 在小程序端复现了,然后在 H5 下不行。。感受到跨端的恶心了

回复 4***@qq.com: 虚假的跨端… 真实的跨端:

哈哈哈哈哈哈哈

回复 yuhespace: 我在 vue2 下使用 this.$nextTick 不生效,这个知道什么原因么?

回复 4***@qq.com: 不应该不生效,我一开始就是2,与2,3无关,它是得DOM更新才会触发 你检查是否有DOM更新,或者是用 let _this = this 让 _this 代替this

回复 yuhespace: 你可以试试,一模一样的代码,真不行,uniapp编译的时候会按照你说的处理this的

你看我之前的代码,h5用直接赋值,微信小程序用$nextTick

回复 yuhespace: 我是说在 vue2 下,用 $nextTick 不生效

在 uni-app 中使用 picker-view 组件时,如果动态修改 picker-view-column 的数据,并且在微信小程序端出现显示不正确的问题,通常是因为微信小程序的 picker-view 组件在数据更新时没有正确刷新视图。

以下是一些可能的原因和解决方案:

1. 数据更新后未触发视图更新

微信小程序的 picker-view 组件在数据更新后,可能需要手动触发视图更新。你可以尝试在数据更新后调用 this.$forceUpdate() 强制更新视图。

this.pickerData = newData; // 更新 picker-view-column 的数据
this.pickerValue = newValue; // 更新 picker-view 的 value
this.$forceUpdate(); // 强制更新视图

2. picker-viewvalue 未正确更新

确保 picker-viewvalue 属性与 picker-view-column 的数据同步更新。如果 value 的值超出了 picker-view-column 的索引范围,可能会导致显示异常。

this.pickerValue = [newIndex]; // 确保 value 的值在合法范围内

3. 使用 key 强制重新渲染

picker-view 组件上使用 key 属性,当数据发生变化时,通过改变 key 的值来强制重新渲染 picker-view

<picker-view :key="pickerKey" :value="pickerValue">
  <picker-view-column>
    <view v-for="(item, index) in pickerData" :key="index">{{ item }}</view>
  </picker-view-column>
</picker-view>
this.pickerData = newData;
this.pickerValue = newValue;
this.pickerKey = Date.now(); // 改变 key 的值,强制重新渲染

4. 确保 picker-view-column 的数据和 value 同步

在动态修改 picker-view-column 的数据时,确保 picker-viewvalue 也同步更新,并且 value 的值在 picker-view-column 的数据范围内。

this.pickerData = newData;
this.pickerValue = [Math.min(newData.length - 1, this.pickerValue[0])]; // 确保 value 不越界

5. 微信小程序的特定问题

微信小程序的 picker-view 组件在某些情况下可能存在 bug 或兼容性问题。如果以上方法都无法解决问题,可以尝试在微信开发者工具中调试,或者检查是否有其他代码影响了 picker-view 的渲染。

6. 使用 setTimeout 延迟更新

在某些情况下,微信小程序的视图更新可能需要一定的时间,可以使用 setTimeout 延迟更新数据。

setTimeout(() => {
  this.pickerData = newData;
  this.pickerValue = newValue;
}, 50);
回到顶部