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月开始的
- 将月份调整到 10 月
- 切换年份到 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
推测是微信小程序的数据与索引问题
经过我的测试,可以使用这种方法解决
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: 你可以试试,一模一样的代码,真不行,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-view
的 value
未正确更新
确保 picker-view
的 value
属性与 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-view
的 value
也同步更新,并且 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);