两个不同类型的uni-datetime-picker使用v-if控制渲染时选择器无法正常展示 uni-app
两个不同类型的uni-datetime-picker使用v-if控制渲染时选择器无法正常展示 uni-app
操作步骤:
<uni-datetime-picker v-if=" flag=== 'date'" v-model="testDate" type="date" />
<uni-datetime-picker v-else v-model="testDaterange" type="daterange" />
```
预期结果:
flag为date时,展示日期选择器,否则展示时间段选择器
实际结果:
实际选择器只会是初次渲染时的类型,例如初次渲染为日期选择,那么即使flag的值更改后,仍渲染为日期选择,不会渲染成时间段选择器。
bug描述:
通过v-if条件控制展示两个不同类型的uni-datetime-picker(type=date和type=daterange)时,选择器无法正确使用
项目信息表
信息类别 | 详情 |
---|---|
产品分类 | uniapp/App |
PC开发环境 | Windows |
PC操作系统版本 | 10 |
HBuilderX类型 | 正式 |
HBuilderX版本 | 3.95 |
手机系统 | Android |
手机系统版本 | Android 14 |
手机厂商 | 模拟器 |
手机机型 | 华为mate30 |
页面类型 | vue |
vue版本 | vue2 |
打包方式 | 云端 |
项目创建方式 | HBuilderX |
3 回复
可以用v-show
<uni-datetime-picker v-show="flag === 'date'" v-model="testDate" type="date" /> <uni-datetime-picker v-show="flag != 'date'" v-model="testDaterange" type="daterange" />试了一下可以解决这个问题,v-if不行是因为内部插槽识别问题吗,我试了很多次v-if确实是有问题
在使用 uni-datetime-picker
组件时,如果你通过 v-if
控制其渲染,可能会遇到选择器无法正常展示的问题。这是因为 v-if
会在条件为 false
时完全销毁组件,当条件变为 true
时重新创建组件,这可能会导致组件的内部状态丢失或初始化问题。
以下是一些可能的解决方案:
1. 使用 v-show
代替 v-if
v-show
是通过 CSS 的 display
属性来控制元素的显示和隐藏,不会销毁和重新创建组件,因此可以避免组件重新初始化的问题。
<template>
<view>
<button @click="togglePicker">切换选择器</button>
<view v-show="showPickerA">
<uni-datetime-picker type="date" v-model="dateA" />
</view>
<view v-show="showPickerB">
<uni-datetime-picker type="datetime" v-model="dateB" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
showPickerA: true,
showPickerB: false,
dateA: '',
dateB: ''
};
},
methods: {
togglePicker() {
this.showPickerA = !this.showPickerA;
this.showPickerB = !this.showPickerB;
}
}
};
</script>
2. 使用 key
强制重新渲染
如果你确实需要使用 v-if
,可以通过给组件添加 key
属性来强制组件在条件变化时重新渲染,这样可以避免一些初始化问题。
<template>
<view>
<button @click="togglePicker">切换选择器</button>
<view v-if="showPickerA">
<uni-datetime-picker type="date" v-model="dateA" key="pickerA" />
</view>
<view v-if="showPickerB">
<uni-datetime-picker type="datetime" v-model="dateB" key="pickerB" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
showPickerA: true,
showPickerB: false,
dateA: '',
dateB: ''
};
},
methods: {
togglePicker() {
this.showPickerA = !this.showPickerA;
this.showPickerB = !this.showPickerB;
}
}
};
</script>
3. 手动触发组件的初始化
如果以上方法都无法解决问题,你可以尝试在组件显示时手动触发组件的初始化逻辑。
<template>
<view>
<button @click="togglePicker">切换选择器</button>
<view v-if="showPickerA">
<uni-datetime-picker type="date" v-model="dateA" ref="pickerA" />
</view>
<view v-if="showPickerB">
<uni-datetime-picker type="datetime" v-model="dateB" ref="pickerB" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
showPickerA: true,
showPickerB: false,
dateA: '',
dateB: ''
};
},
methods: {
togglePicker() {
this.showPickerA = !this.showPickerA;
this.showPickerB = !this.showPickerB;
if (this.showPickerA) {
this.$nextTick(() => {
this.$refs.pickerA.init(); // 假设组件有 init 方法
});
}
if (this.showPickerB) {
this.$nextTick(() => {
this.$refs.pickerB.init(); // 假设组件有 init 方法
});
}
}
}
};
</script>