在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
Nov 25 Javascript
日期 时间js控件
May 07 Javascript
jQuery之选择组件的深入解析
Jun 19 Javascript
Angularjs 基础入门
Dec 26 Javascript
angularjs 表单密码验证自定义指令实现代码
Oct 27 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
Mar 30 Javascript
深究AngularJS之ui-router详解
Jun 13 Javascript
关于页面刷新vuex数据消失问题解决方案
Jul 03 Javascript
简单实现js上传文件功能
Aug 21 Javascript
bootstrap3-dialog-master模态框使用详解
Aug 22 Javascript
JS实现数组简单去重及数组根据对象中的元素去重操作示例
Jan 05 Javascript
Vue实现多页签组件
Jan 14 Vue.js
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
适用于抽奖程序、随机广告的PHP概率算法实例
2014/04/09 PHP
php基于Snoopy解析网页html的方法
2015/07/09 PHP
laravel利用中间件防止未登录用户直接访问后台的方法
2019/09/30 PHP
JS location几个方法小姐
2008/07/09 Javascript
javascript实现2048游戏示例
2014/05/04 Javascript
基于jQuery实现的双11天猫拆红包抽奖效果
2015/12/01 Javascript
AnglarJs中的上拉加载实现代码
2018/02/08 Javascript
vue动态绑定组件子父组件多表单验证功能的实现代码
2018/05/14 Javascript
JavaScript中this的全面解析及常见实例
2019/05/14 Javascript
使用layui前端框架弹出form表单以及提交的示例
2019/10/25 Javascript
详解python发送各类邮件的主要方法
2016/12/22 Python
Python实现获取nginx服务器ip及流量统计信息功能示例
2018/05/18 Python
python实现requests发送/上传多个文件的示例
2018/06/04 Python
python实现监控某个服务 服务崩溃即发送邮件报告
2018/06/21 Python
Python GUI编程完整示例
2019/04/04 Python
python中while和for的区别总结
2019/06/28 Python
如何在Django配置文件里配置session链接
2019/08/06 Python
Python二元赋值实用技巧解析
2019/10/25 Python
Python for i in range ()用法详解
2020/09/18 Python
对python中 math模块下 atan 和 atan2的区别详解
2020/01/17 Python
在python中利用dict转json按输入顺序输出内容方式
2020/02/27 Python
python判断一个变量是否已经设置的方法
2020/08/13 Python
基于CSS3的animation属性实现微信拍一拍动画效果
2020/06/22 HTML / CSS
详解移动端Html5页面中1px边框的几种解决方法
2018/07/24 HTML / CSS
美国巧克力喷泉品牌:Sephra
2019/05/05 全球购物
康拓普公司Java笔面试
2016/09/23 面试题
Android面试题附答案
2014/12/08 面试题
运动会广播稿200米
2014/01/27 职场文书
主题实践活动总结
2014/05/08 职场文书
综艺节目策划方案
2014/06/13 职场文书
销售竞赛活动方案
2014/08/23 职场文书
邮政营业员岗位职责
2015/04/14 职场文书
2015年度质量工作总结报告
2015/04/27 职场文书
活动费用申请报告
2015/05/15 职场文书
退税申请报告怎么写
2015/05/18 职场文书
TV动画《间谍过家家》公开PV
2022/03/20 日漫