uView的DatetimePicker组件在confirm回调中取不到v-model的最新值

前情

uni-app是我比较喜欢的跨平台框架,它能开发小程序/H5/APP(安卓/iOS),重要的是对前端开发友好,自带的IDE让开发体验非常棒,公司项目就是主推uni-app,在uniapp生态中uView是其中非常好的全平台的第三方开源ui库,我在公司项目中果断的使用了它。

我一个过滤弹窗有二个表单需要选择开始日期和结束日期,于是想到复用一个日期选择组件,通过设置不同标志来区分是不同表单触发的,再在confrim回调里根据不同标志把v-model上的值赋值到不同表单上

示例代码片段:

<template>
	<view class="page-container">
		<custom-popup 
			:isVisble="filterFormVisible" 
			custom-style="top:206rpx;" 
			@maskClick="fliterFormToggle"
		>
			<view class="filter-main">
				<view class="filter-content">
					// ......
					<text class="filter-type">入驻时间:</text>
					<view class="filter-item-date-wrap">
								<u-input 
									v-model="filterDateStart" 
									placeholder="选择开始时间" 
									readonly 
									@click.native="pickerDate('filterDateStart')"
								>
									<text slot="prefix" class="iconfont">&#xe65f;</text>
								</u-input>
								<view class="filter-connect"></view>
								<u-input 
									v-model="filterDateEnd" 
									placeholder="选择结束时间" 
									readonly 
									@click.native="pickerDate('filterDateEnd')"
								>
									<text slot="prefix" class="iconfont">&#xe65f;</text>
								</u-input>
							</view>
				</view>
				// ......
			</view>
		</custom-popup>
		
		// 日期选择器
		<u-datetime-picker
			:show="showDatePicker"
			ref="datetimePicker"
			mode="date"
			v-model="filterDate"
			:formatter="formatter"
			@cancel="showDatePicker = false"
			@confirm="confirmFilterDate"
		/>
		
	</view>
</template>

<script>
	import customPopup from '../../components/customPopup/customPopup.vue';
	
	export default {
		components: {
			customPopup
		},
		data() {
			return {
				filterFormVisible: false,
				showDatePicker: false,
				filterDateStart: '',
				filterDateEnd: '',
				filterDate: new Date().getTime()
			}
		},
		mounted() {
			// 微信小程序需要用此写法
			this.$refs.datetimePicker.setFormatter(this.formatter)
		},
		methods: {
			filterDateChange(e) {
				console.log('---- filterDateChange ----:', e);
				this.filterForm.regDate = e.detail.value;
			},
			filterReset() {
				
			},
			filterSubmit() {
				
			},
			fliterFormToggle() {
				this.filterFormVisible = !this.filterFormVisible;
			},
			pickerDate(type) {
				this.showDatePicker = true;
				// 标志变量,用于区分是哪个表单触发的
				this.dateType = type;
			},
			confirmFilterDate() {
				console.log('---- confirmFilterDate ----:', this.filterDate);
				// 通过标志变量,把值赋值到正确的表单上
				this[this.dateType] = e.value;
				this.showDatePicker = false;
			},
			formatter(type, value) {
				if (type === 'year') {
					return `${value}年`
				}
				if (type === 'month') {
					return `${value}月`
				}
				if (type === 'day') {
					return `${value}日`
				}
				return value
			},
		}
	}
</script>

// ......

坑位

但是事与愿违,在confirm回调里取到v-model绑定的值不是最新的,而是上一次的值,更奇怪的是你点击二次就能拿到最新的值了

Why?

通过看了DatetimePicker的源码发现,引起这个问题的原因很简单,因为它的代码是先触发confirm回调,再才触发input事件去更新v-model上的值,当你在confirm回调去取值的时候,值还没有更新,点第二次可以那是因为值已经更新了。

组件源码片段如下:

......

// 点击工具栏的确定按钮
confirm() {
	this.$emit('confirm', {
		value: this.innerValue,
		mode: this.mode
	})
	this.$emit('input', this.innerValue)
},
......

解决方案

方案1

既然发现是因为更新延后,我们可以加个定时器来获取

示例代码片段:

......
confirmFilterDate() {
		console.log('---- confirmFilterDate ----:0', this.filterDate);
		setTimeout(() => {
			console.log('---- confirmFilterDate ----:1', this.filterDate);
			// 通过标志变量,把值赋值到正确的表单上
			this[this.dateType] = this.filterDate;
			this.showDatePicker = false;
		}, 0);
	},
......

方案2

通过vue自带的$nextTick来解决

示例代码片段:

......
confirmFilterDate() {
	console.log('---- confirmFilterDate ----:0', this.filterDate);
	this.$nextTick(() => {
		console.log('---- confirmFilterDate ----:1', this.filterDate);
		this[this.dateType] = this.filterDate;
		this.showDatePicker = false;
	})
},
......

方案3(目前推荐)

其实可以不用依赖v-model值,confirm回调有把最新的日期选择值传回来,直接取那个值即可

示例代码片段:

confirmFilterDate(e) {
	console.log('---- confirmFilterDate ----:0', this.filterDate, e);
	this[this.dateType] = e.value;
	this.showDatePicker = false;
},

或者可以再等等,我有向uView官方提了一个PR:https://github.com/umicro/uView2.0/pull/1068 希望能优化这一个问题,如果能合并那后续就可以在confirm回调里愉快的获取v-model最新值了。

posted @ 2024-06-18 19:07  !win !  阅读(472)  评论(0)    收藏  举报