在Vant的基础上封装下拉日期控件的代码示例


Posted in Javascript onDecember 05, 2018

需求分析

在实际项目中,表单里面的日期选择是常用的组件。Vant有提供日期组件,但是居然没有提供下拉形式的日期组件,不过该有的元件都有,就自己封装一个。

封装组件过程中我们要解决:

  • 和表单的样式能兼容
  • 错误提示
  • 参数问题
  • 事件机制
  • 格式化

解决问题

就给新的组件取名为 VantFieldDate

期望使用的时候是这样的

<vant-field-date
 label="发布时间"
 v-model="formData.publishDate"
 type="datetime"
 :max-date="new Date()"
/>

具体实现,我贴上代码详细讲解。

<template>
 <div class="vant-field-date">
  <van-cell
   :title="label"
   :class="{'readonly': readonly, 'placeholder' : text}"
   :is-link="!readonly"
   :required="required"
   @click="show">
   <!-- 显示当前值,没有值显示提示文字 -->
   {{ text ? text : placeholder }}
   <!-- 自定义错误显示 -->
   <div
    v-if="$attrs.error"
    v-text="$attrs['error-message']"
    class="van-field__error-message"
   />
  </van-cell>
  <!-- 用 actionsheet 来包裹弹出层日期控件 -->
  <van-actionsheet v-model="isShowPicker">
   <!-- $attrs 可以把根节点的attr放到目标组件上,如此可以像使用 DatePicker 组件一样使用这个新组件 -->
   <van-datetime-picker
    v-bind="$attrs"
    :type="type"
    title="请选择日期"
    :min-date="minDate"
    :max-date="maxDate"
    @cancel="cancel"
    @confirm="confirm"
   />
  </van-actionsheet>
 </div>
</template>

<script>
 export default {
  name: 'VantFieldDate',
  inheritAttrs: false, // https://cn.vuejs.org/v2/api/#inheritAttrs
  props: {
   value: {
    type: [Number, Date],
    default: undefined // 值不能是 null,DatePicker会报错
   },
   // Cell 显示的文字
   label: {
    type: String,
    default: null
   },
   // 必填的星号
   required: {
    type: Boolean,
    default: false
   },
   // 只读状态
   readonly: {
    type: Boolean,
    default: false
   },
   // 占位提示文字
   placeholder: {
    type: String,
    default: '请选择'
   },
   // 展示的格式化
   format: {
    type: String,
    default: null
   }
  },
  data() {
   return {
    selectedItem: null,
    isShowPicker: false
   }
  },
  computed: {
   // 展示的格式化,时间提交的值是Date类型数据
   formatFormula() {
    if(this.format){
     return this.format
    } else if (this.type === 'date') {
     return 'yyyy-MM-dd'
    } else if (this.type === 'datetime') {
     return 'yyyy-MM-dd hh:mm'
    } else if (this.type === 'time') {
     return 'hh:mm'
    } else if (this.type === 'year-month') {
     return 'yyyy-MM'
    }
   },
   text() {
    return this.value ? this.dateFormat(this.value, this.formatFormula) : ''
   }
  },
  methods: {
   dateFormat: (value, format) => {
    if (!value) return
    if (!(value instanceof Date)) {
     value = new Date(value)
    }
    let o = {
     'M+': value.getMonth() + 1, // month
     'd+': value.getDate(), // day
     'h+': value.getHours(), // hour
     'm+': value.getMinutes(), // minute
     's+': value.getSeconds(), // second
     'q+': Math.floor((value.getMonth() + 3) / 3), // quarter
     'S': value.getMilliseconds() // millisecond
    }

    if (!format || format === '') {
     format = 'yyyy-MM-dd hh:mm:ss'
    }

    if (/(y+)/.test(format)) {
     format = format.replace(RegExp.$1, (value.getFullYear() + '').substr(4 - RegExp.$1.length))
    }

    for (let k in o) {
     if (new RegExp('(' + k + ')').test(format)) {
      format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
     }
    }
    return format
   },
   show() {
    if (!this.readonly) {
     this.isShowPicker = true
    }
   },
   confirm(value) {
    // 更新 v-model 绑定的 value 值,第二个参数是毫秒数,第三个参数是原始值,根据自己的项目的数据结构来修改
    // input 事件同时也会触发 vee-validate 的验证事件
    this.$emit('input', value.getTime(), value)
    // onChange事件,虽然重写 @input可以实现,但这样会破坏 v-model 写法。
    this.$emit('change', value.getTime(), value)
    this.cancel()
   },
   // 隐藏弹框
   cancel() {
    this.isShowPicker = false
   }
  }
 }
</script>

效果

在Vant的基础上封装下拉日期控件的代码示例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 自动填写表单的实现方法
Apr 09 Javascript
javascript中数组的多种定义方法和常用函数简介
May 09 Javascript
jQuery实现将页面上HTML标签换成另外标签的方法
Jun 09 Javascript
javascript判断firebug是否开启的方法
Nov 23 Javascript
bootstrap多种样式进度条展示
Dec 20 Javascript
jQuery中select与datalist制作下拉菜单时的区别浅析
Dec 30 Javascript
利用Vue.js框架实现火车票查询系统(附源码)
Feb 27 Javascript
使用JavaScriptCore实现OC和JS交互详解
Mar 28 Javascript
详解Angular 4 表单快速入门
Jun 05 Javascript
实例讲解DataTables固定表格宽度(设置横向滚动条)
Jul 11 Javascript
JS原生数据双向绑定实现代码
Aug 14 Javascript
微信小程序用户授权弹窗 拒绝时引导用户重新授权实现
Jul 29 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
Dec 05 #Javascript
微信小程序实现图片滚动效果示例
Dec 05 #Javascript
详解vue中的computed的this指向问题
Dec 05 #Javascript
使用rollup打包JS的方法步骤
Dec 05 #Javascript
微信小程序入门之广告条实现方法示例
Dec 05 #Javascript
Vue实现本地购物车功能
Dec 05 #Javascript
node和vue实现商城用户地址模块
Dec 05 #Javascript
You might like
Zend Framework实现具有基本功能的留言本(附demo源码下载)
2016/03/22 PHP
浅谈php中的访问修饰符private、protected、public的作用范围
2016/11/20 PHP
thinkPHP5.0框架API优化后的友好性分析
2017/03/17 PHP
laravel 根据不同组织加载不同视图的实现
2019/10/14 PHP
Javascript 函数对象的多重身份
2009/06/28 Javascript
IE与Firefox在JavaScript上的7个不同写法小结
2009/09/14 Javascript
JS 文件大小判断的实现代码
2010/04/07 Javascript
jQuery源码分析之Event事件分析
2010/06/07 Javascript
基于jquery的合并table相同单元格的插件(精简版)
2011/04/05 Javascript
捕获键盘事件(且兼容各浏览器)
2013/07/03 Javascript
jquery图片切换实例分析
2015/04/15 Javascript
jQuery表格行上移下移和置顶的实现方法
2015/10/08 Javascript
浅谈Node.js:Buffer模块
2016/12/05 Javascript
JavaScript用构造函数如何获取变量的类型名
2016/12/23 Javascript
vue实现分页组件
2020/06/16 Javascript
JavaScript前端页面搜索功能案例【基于jQuery】
2019/07/10 jQuery
微信小程序获取当前时间及星期几的实例代码
2020/09/20 Javascript
PyTorch读取Cifar数据集并显示图片的实例讲解
2018/07/27 Python
python中文编码与json中文输出问题详解
2018/08/24 Python
浅谈python requests 的put, post 请求参数的问题
2019/01/02 Python
python实现集中式的病毒扫描功能详解
2019/07/09 Python
python3实现斐波那契数列(4种方法)
2019/07/15 Python
细数nn.BCELoss与nn.CrossEntropyLoss的区别
2020/02/29 Python
新闻记者实习自我鉴定
2013/09/19 职场文书
人事档案接收函
2014/01/12 职场文书
前处理组长岗位职责
2014/03/01 职场文书
医院领导班子四风问题对照检查材料
2014/10/26 职场文书
2014年工商所工作总结
2014/12/09 职场文书
中学教师个人总结
2015/02/10 职场文书
后勤个人工作总结
2015/02/28 职场文书
会议通知格式范文
2015/04/15 职场文书
幼儿园六一主持词
2015/06/30 职场文书
运动员入场词
2015/07/18 职场文书
浅谈如何提高PHP代码的质量
2021/05/28 PHP
Spring Cloud Gateway去掉url前缀
2021/07/15 Java/Android
关于EntityWrapper的in用法
2022/03/22 Java/Android