当需求存在tab切换展示uni-datetime-picker,且每次切换需要初始化默认选中日期的时候,就会出现这样的bug。
就以两个不同类型的日期选择框进行切换展示为例:
没填坑之前的代码:
<uni-datetime-picker v-show="activeTab==='part'" type="date" v-model="searchTime"/>
<uni-datetime-picker v-show="activeTab==='all'" type="daterange" v-model="searchTimeRange"/>
//初始化data的数据
data() {
return {
searchTime: '',
searchTimeRange:'',
}
},
created() {
this.searchTime = getThisDate(); //getThisDate获取当天日期方法
this.searchTimeRange = getThisWeek(); //getThisWeek获取本周日期的方法
},
methods: {
changeTab(data) {
if(data.name===this.activeTab)return; //点击相同tab时阻止
//切换时重置日期
this.searchTime = getThisDate();
this.searchTimeRange = getThisWeek();
this.activeTab = data.name;
this.getList();
}
显示结果:当选择到其他日期,再切换tab。单个日期选择的选择框是重置的日期,但选择的日历还是前面选择的日期;日期范围选择器的选择框也重置了日期,但选择的日历选中了三个日期。
填坑之路:
最开始想的是组件内日历组件 数据失去响应式或没有重新加载。就简单暴力的用v-if,但结果就是:日期回显不出来,日期选择不能选中,组件完全失效。
然后想到,既然daterange的效果是之前选中的结束日期还在存在,那就在切换时先置空,再赋值本周日期。结果很理想,效果实现。
changeTab(data) {
if(data.name===this.activeTab)return;
this.searchTime = getThisDate();
this.searchTimeRange = []; //rang选择日期范围的需要重置为空数组,再进行赋值。否则会出现回显错误
this.activeTab = data.name;
setTimeout(_=>{
this.searchTimeRange = getThisWeek(); //重新赋值本周
this.goTop();
this.getWorkPlanList();
},0)
},
但单个日期选择date组件使用这个方法直接完全没有用,还导致最开始选中的时间也没有选中了。因此,就需要对uni-datetime-picker组件的代码进行改造。找到uni_modules文件夹下的uni-datetime-picker.vue文件。
会发现,watch监听value时有个判断.当满足这个判断条件时,就不会再去更新日历组件上面选中的日期。当切换重新赋值,打印isEmitValue会发现非初次赋值日期时为true,满足条件就不会去更新视图选中。
所以可以从父组件上再传一个参数来,判断是否需要刷新视图。改造后的代码如下:
<uni-datetime-picker v-show="activeTab==='part'" type="date"
v-model="searchTime" :isAnyRefresh="true"/>
在uni-datetime-picker组件内props:
watch的判断增加条件:
完美,收官!!!