前情

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"></text>
</u-input>
<view class="filter-connect"></view>
<u-input
v-model="filterDateEnd"
placeholder="选择结束时间"
readonly
@click.native="pickerDate('filterDateEnd')"
>
<text slot="prefix" class="iconfont"></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最新值了。

uView的DatetimePicker组件在confirm回调中取不到v-model的最新值的更多相关文章

  1. Thymeleaf模板引擎与springboot关联后,在html中无法使用el表达式获取model存的值

    头部引入了thymeleaf <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thy ...

  2. uView的DatetimePicker详解

    uView UI号称: 是全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水 亲身感受,用起来真的坑太多, 官方文档太简洁, 很多配置都没说明也没代码, 上百度查 ...

  3. Android异步回调中的UI同步性问题

    Android程序编码过程中,回调无处不在.从最常见的Activity生命周期回调开始,到BroadcastReceiver.Service以及Sqlite等.Activity.BroadcastRe ...

  4. React onBlur回调中使用document.activeElement返回body解决方案

    最开始想实现一个功能,点击img图标后给出购物下拉框CartDropdown,当img及CartDropdown失去焦点时隐藏CartDropdown. 最开始的核心代码如下: export defa ...

  5. ajax回调中的this.href不执行跳转的解决办法

    1. 问题背景 如下所示代码: $.post("/ems/register",indata, function(data){ if(data != null && ...

  6. jQuery:在一个回调中处理多个请求

    我曾经为Mozilla Developer Network 开发一个新功能,它需要加载一个基本的脚本文件的同时加载一个JSON请求.因为我们使用的是jQuery,意味着要使用 jQuery.getSc ...

  7. 使用domain模块捕获异步回调中的异常

    和其他服务器端语言相比,貌似node.js 对于异常捕捉确实非常困难. 首先你会想到try/catch ,但是在使用过程中我们会发现并没有真正将错误控制在try/catch 语句中. 为什么? 答案是 ...

  8. Maya cmds pymel scriptJob() 和 undoInfo() 在回调中撤销(undo)

    Maya cmds pymel scriptJob() 和 undoInfo() 在回调中撤销(undo) def myEventFun(): cmds.undoInfo(stateWithoutFl ...

  9. model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转;解决的方法是用responsewrite(普通的字符响应)

    model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转:解决的方法是用responsewrite

  10. 使用Unity中的Box Collider组件完成游戏场景中的碰撞检测功能

    一.介绍 目的:通过Unity自带的组件完成游戏场景中的碰撞检测功能. 软件环境:Unity 2017.3.0f3 二.实现过程 1,在面板中点击Add Component按钮 2,添加Box Col ...

随机推荐

  1. 利用PaddleHub 进行人脸检测识别、并对图片进行抠图

    利用PaddleHub 进行人脸检测识别.并对图片进行抠图   本文是利用百度的飞桨平台的paddle进行人脸的检测和抠图,但是里面也有一些小问题,特记录一下笔记,以便以后观看学习. 环境:pytho ...

  2. 5G网元功能与接口

    5G网元功能与接口 5G移动通信整体网络架构 5G网络功能之间的信息交互可以基于两种方式表示:其一为基于服务表示:其二为基于点对点表示.实时部署时,也可以采用两种方式相结合的表示方式. 并不是所有的接 ...

  3. Spring —— 注解开发(总结)

    XML配置与注解配置对比   

  4. CSP-S 2023

    T1 直接 \(10^{5}\) 枚举状态就过了,合法的非零差分数量只可能为 \(1,2\)(\(0\) 相当于没转,按照题意 "都不是正确密码" 是不符的) 需要注意的是形如 0 ...

  5. 北京智和信通 | 无人值守的IDC机房动环综合监控运维

    随着信息技术的发展和全面应用,数据中心机房已成为各大企事业单位维持业务正常运营的重要组成部分,网络设备.系统.业务应用数量与日俱增,规模逐渐扩大,一旦机房内的设备出现故障,将对数据处理.传输.存储以及 ...

  6. uniapp电子签名盖章实现详解

    项目开发中用到了电子签名.签好名的图片需要手动实现横竖屏旋转.并将绘制的签名图片放到pdf转换后的base64的图片上,可以手动拖动签名到合适的位置,最后合成签名和合同图片并导出.和以往一样,先发一下 ...

  7. C# 的运算符和作用域

    // C# 运算符 // 表达式 表达式有操作数(operand)和运算符(operator)构成: // 常见的运算符 + - * / 和 new // x ?? y 如果x为null, 则计算机过 ...

  8. kotlin类与对象——>对象表达式与对象声明、内联类

    1.对象表达式与对象声明 有时候,我们需要创建一个对某个类做了轻微改动的类的对象,而不用为之显式声明新的子类.Kotlin 用对象表达式和对象声明处理这种情况 2.对象表达式 要创建一个继承自某个(或 ...

  9. 华为云-容器引擎CCE-基本概念

    云容器引擎(Cloud Container Engine,简称CCE)提供高度可扩展的.高性能的企业级Kubernetes集群,支持运行Docker容器.借助云容器引擎,您可以在华为云上轻松部署.管理 ...

  10. Go语言基础06 _function

    Go语言基础06 _function 函数在Go语言中是一等公民 与其他主要编程语言的差别 可以有多个返回值 所有参数都是值传递:slice,map,channel 会有传引用的 错觉 函数可以作为变 ...